Is ChatGPT/Codex replacing Developers?

Is ChatGPT/Codex replacing Developers?

Here is the sentiment I echo

INTRO

“A little learning is a dangerous thing.

Drink deep, or taste not the Pierian Spring;

There shallow draughts intoxicate the brain,

and drinking largely sobers us again.”

This is a quote from Alexander Pope's poem "An Essay on Criticism". The phrase "a little learning is a dangerous thing" means that having only a superficial or incomplete understanding of a topic can be more harmful than having no knowledge at all.

The second line, "Drink deep, or taste not the Pierian Spring", refers to the Pierian Spring, a fountain in ancient Greece that was believed to be the source of inspiration for the Muses. Pope is saying that if you are going to learn something, you should learn it thoroughly and deeply, rather than just skimming the surface.

The third line, "There shallow draughts intoxicate the brain", means that only learning a little bit can give a person a false sense of knowledge and lead them to make mistakes. Just as drinking small amounts of alcohol can make a person feel intoxicated, learning only a little bit can make someone feel overconfident and lead to poor decision-making.

The final line, "and drinking largely sobers us again", means that by learning deeply and comprehensively, we gain a fuller understanding of a topic and are less likely to be misled by our own limited knowledge. Just as drinking more alcohol can sober someone up by diluting the alcohol already in their system, learning more can clarify our thinking and help us avoid mistakes caused by incomplete knowledge.

In summary, the quote is advising us to seek a thorough and deep understanding of a topic, rather than just a surface-level understanding, in order to avoid the dangers of incomplete knowledge.

The internet is swarmed with articles that ChatGPT would take away several kinds of jobs. In this post, I am going to test ChatGPT with the premise that it can take away the job of a software developer. Let's see if has a deep understanding of the matter. Or it will just create a superficial engineer?
Also, remember that the cut-off date even for GPT-4 is around September 2021.

Conversation

I asked ChatGPT to be an assistant in developing a Nuxt.js application that would allow me to upload the files to Azure Blob Storage.
In the first iteration, it provided me with a naive code that will let me upload a file to blob storage.

<template>
  <div>
    <h1>Upload file to Azure Blob Storage</h1>
    <form @submit.prevent="onSubmit">
      <div>
        <label for="file">Select file:</label>
        <input type="file" id="file" ref="fileInput" />
      </div>
      <button type="submit">Upload</button>
    </form>
  </div>
</template>

<script>
import blobServiceClient from '~/plugins/azureBlob'

export default {
  methods: {
    async onSubmit() {
      const file = this.$refs.fileInput.files[0]
      const containerName = 'my-container'
      const blobName = file.name
      const containerClient = blobServiceClient.getContainerClient(containerName)
      const blockBlobClient = containerClient.getBlockBlobClient(blobName)
      const uploadOptions = { blobHTTPHeaders: { blobContentType: file.type } }
      await blockBlobClient.uploadBrowserData(file, uploadOptions)
      console.log('File uploaded successfully')
    }
  }
}
</script>

But this is not how an actual file uploader should work. What if the file uploads fail in between? This doesn't provide any resumability or a retry mechanism in case upload stalls in between for any reason.
So, for the next instruction, I asked it to add resume functionality to it. It added a resume code but without the code for creating chunks of the files for independent uploads. I then prompted it to provide me with the code for it.
Nice, that looked good.

async onSubmit() {
  const file = this.$refs.fileInput.files[0]
  const containerName = 'my-container'
  const blobName = file.name
  const containerClient = blobServiceClient.getContainerClient(containerName)
  const blockBlobClient = containerClient.getBlockBlobClient(blobName)
  const existingBlob = await blockBlobClient.getProperties().catch(() => null)
  const fileSize = file.size
  const maxBlockSize = 4 * 1024 * 1024 // 4 MB
  const numberOfBlocks = Math.ceil(fileSize / maxBlockSize)
  const blockIds = []
  let offset = 0
  for (let i = 0; i < numberOfBlocks; i++) {
    const blockId = btoa(`block-${i}`)
    blockIds.push(blockId)
    const blockData = file.slice(offset, offset + maxBlockSize)
    const uploadOptions = {
      blobHTTPHeaders: { blobContentType: file.type },
      onProgress: progress => console.log(`Uploaded ${progress.loadedBytes} bytes`)
    }
    if (existingBlob && offset < existingBlob.contentLength) {
      await blockBlobClient.stageBlockWithResponse(blockId, blockData, offset, {
        leaseAccessConditions: { modifiedAccessConditions: { ifMatch: existingBlob.etag } },
        ...uploadOptions
      })
    } else {
      await blockBlobClient.stageBlockWithResponse(blockId, blockData, offset, uploadOptions)
    }
    offset += maxBlockSize
  }
  if (existingBlob) {
    const uploadOptions = { blobHTTPHeaders: { blobContentType: file.type } }
    await blockBlobClient.commitBlockListWithResponse(blockIds, {
      leaseAccessConditions: { modifiedAccessConditions: { ifMatch: existingBlob.etag } },
      ...uploadOptions
    })
  } else {
    const uploadOptions = { blobHTTPHeaders: { blobContentType: file.type } }
    await blockBlobClient.commitBlockListWithResponse(blockIds, uploadOptions)
  }
  console.log('File uploaded successfully')
}

But for the code snippet above, the methods stageBlockWithResponse and commitBlockListWithResponse do not exist. I replied that these methods do not exist. ChatGPT suggested alternates, but those won't compile as well. We hit the hallucination stage of LLM pretty quickly. And finally, it ended up replacing the code entirely different from the code it emitted. Now even as a developer, you are lost!!

Then, I had to spend time browsing the documentation for the correct methods that I should use. So, I was back to how it was supposed to actually be done, reading the documentation.
Finally, I found those missing methods and corrected the code, which worked like a charm. As, a developer with some experience and intuition, ChatGPT was able to make my life easier. Yea, I understand there maybe a few ready-made libraries available to provide the same functionality, so, I needn't code my version of it. But that's fine for now.

Pitfalls

Let's see some of the dimensions where AI assistants would need assistance themselves:

  1. Code Quality: The code above may not follow the required coding guidelines. For instance, I asked ChatGPT to refactor the code into smaller functions. It did that effectively. So, the code quality would also vary depending on the subject matter.

  2. Security: It may be possible that the AI assistant is trained on a vulnerable piece of code. This is, however, not easy even for seasoned developers to keep track of. So, static code analysis tools like code scanning, and automatic upgrades on dependencies should be in place. Regular security reviews and testing are critical to ensuring the security of the code.

  3. Compatibility: This is the case we saw above, where the method that ChatGPT generated did not exist in the version of the library I imported. It would be challenging sometimes to find what is wrong in the generated code and what would be the correct equivalence in the latest version.

  4. AI reliance: It is also possible that AI generates code that is hard to understand or the developer has a shallow understanding of it. In that case, updating the code with any customization becomes very difficult.

  5. Debugging: Debugging code generated by AI assistants can be challenging, as it may be difficult to understand the underlying logic and identify errors. This can be because the AI assistant may use complex algorithms or generate code that is difficult to read and understand.

  6. Documentation:
    AI assistants can also generate some level of documentation of the generated code. But it would be the responsibility of developers to review that documentation and update not-so-obvious pieces of code with proper documentation.

Conclusion

Software engineering is a complex and constantly evolving field, with many different tools, technologies, and methodologies. If a developer has only a superficial understanding of a particular technology or methodology, they may try to apply it in inappropriate situations, resulting in bugs or poor performance. They may also make design decisions based on incomplete or incorrect information, leading to poorly designed software.

In addition, a developer with only a limited understanding of software engineering concepts may overestimate their abilities and take on tasks beyond their expertise. This can lead to missed deadlines, poor-quality code, and other problems that can impact the success of the project.

So, we see that AI is not replacing Software Developers anytime sooner.
Software development still needs a lot of things as listed above in order to produce a robust application. However, a lot of effort would shift towards testing the code and other non-functional aspects of it. It seems it would reduce turnaround time for software development only if the developers spend time understanding the generated code and have it documented properly, else, the gains received in auto-generation would be lost while updating and debugging the code as the software matures.

Note: The line-by-line explanation of the quote was generated using ChatGPT.

https://github.com/SuperMohit/file-uploader