Write comments for code

Last edited time
Feb 15, 2024 1:06 PM
Reading list
Status
1 case
tags
documentation

Case 1: Writing code annotations

Our main aim was to create documentation for all the classes, protocols, and functions in the KYC flow of an IOS banking application. The original code was quite complex and a bit of a puzzle, lacking any documentation.

Used GitHub Copilot Chat and Cursor Chat.

Lessons learned

Break the task into smaller segments

Prompts like “write documentation for this 200 lines long file” usually don't yield optimal results. It's far more effective to ask the chat to describe classes incrementally. Given that the chat can only handle limited context, it's more efficient for it to gather information about specific functions rather than an entire file.

Additionally, GPT tends to generate more meaningful annotations for a class when there are existing comments in its code.

Control the context of the chat

Both Copilot Chat (since 0.12.1 version) and Cursor Chat allow adding specific files to the chat context. Copilot has # for this purpose (e.g., #file:MyFile.swift), while Cursor employs the "@" symbol (@MyFile.swift). Cursor Chat provides more flexibility in terms of what can be added to the context, allowing inclusion of specific code snippets from various files or even entire folders. However, these tags essentially function in a similar manner.

What’s more important, simply adding a file to the project doesn't guarantee that the GPT model will utilize that specific file when generating a response. At times, Copilot Chat may disregard the currently opened tab, even when explicitly mentioned in the prompt (potentially a bug).

To include the entire project in the prompt, the tag @workspace (Copilot) and “with codebase” option (Cursor) can be used. In this case, some of the project files will be included in the prompt automatically. It can improve the response if the related files are contextually significant. On the other hand, for local functions or classes, excluding the workspace may be preferable, as its inclusion can lead to confusion for GPT, resulting in a potentially ambiguous final output.

All in all, the context is important for satisfactory results, but it may require some time and/or multiple attempts before Copilot or Cursor precisely uses the necessary files.

Provide an example

AI assistants perform well when provided with examples. For example, we encountered a scenario where we had several similar protocols and aimed to describe them uniformly. At first we tried to generate an annotation for all of them at once, but failed, as the results varied for each protocol. However, when an example was provided and the prompt was rephrased to “complete the rest of the annotations taking X as example”, the result improved drastically.

It is important to note that the number of provided examples also matters. Providing 2-3 good examples to the chat yields a more stable outcome.

Overall, the following algorithm proves effective:

  1. Generate a result for one entity.
  2. Manually correct if needed, as similar minor issues may persist in future outputs.
  3. Generate a result for the second entity, referring to the first.
  4. Manually correct if needed.
  5. Generate the result for the remaining entities

Inline Chat often excels at generating repetitive code sections, although using it repeatedly in the same file can be quite tiring. In our case, we used it to generate annotations for the second protocol and then switched to Copilot Chat for the subsequent entities.

How to keep the answer short

Big responses didn’t seem like a big problem until we decided to solve it. Some private functions didn’t require 10-lines-long explanations, but all the continuous attempts to make the output shorter were unsuccessful. “Keep it short” didn’t work at all (even resorting to some colorful language and doubling this condition), moreover, directly specifying the desired number of lines caused GPT to consolidate the answer into a few overly long lines.

We then adopted a different strategy: pasting the original long response and asking Copilot/Cursor to shorten it, rather than trying to generate a short response from the start. That worked, and to refine it further we repeated the prompt for the shortened response. This recursive method was highly effective, so we continued to use it for other cases as well.

It's worth mentioning that the quality of the shortened response depends on the quality of the original message.

Pitfalls

Broken context

Sometimes chat’s understanding of context breaks, leading to responses like “I can only imagine what the function named X would look like, but here is an approximate annotation”. This occurs even when the function is selected in the open tab and when the chat itself references this code range in its responses.

The context control is also inconsistent. The referenced material may sporadically include files mentioned by #, or only one of multiple files may be incorporated.

Best prompts

Protocol documentation

V2

I need you to write an annotation for the @IKycStorage.swift . Use best practices on writing documentation for iOS projects in Swift language. Target audience is iOS developers. Don't fucking write useless comments, just what needed to understand the code. For better understanding on what is happening look up for protocol's usages in @ChatFlowService.swift and @KYCChatInteractor.swift . I need the documentation to be related to the context of the KYC chat flow. Don't mention related classes in the annotation directly. Write the comment in multiline style. If paragraphs are longer than 150 symbols, break them into lines no longer than 150 symbols. Don't describe the parameters of the protocol.

Function documentation

V3 - should be applied with @workspace tag and while the function code is selected

Write a documentation for the function fireNextState. I need the documentation to be related to the context of the KYC chat flow. Briefly describe what it does, what are its parameters and what it returns. Don't fucking leave useless comments. Use best practices on writing documentation for iOS projects in Swift language. The target audience is iOS developers. All the annotations should be in the multiline style (not in ///). All the lines and sentences should be no longer than 120 symbols. For fuck's sake, keep only necessary information. Don't expand abbreviations. Ideally all the annotation should be no longer than 3 lines

Class annotation

V1 - should be applied with @workspace tag and while the class code is selected (at least partially)

I need you to write an annotation for the AddressInfoMessage class. Use best practices on writing documentation for iOS projects in Swift language. Target audience is iOS developers. Don't fucking write useless comments, just what needed to understand the code. I need the documentation to be related to the context of the KYC chat flow. Don't mention related classes in the annotation directly. Write the comment in multiline style. If paragraphs are longer than 150 symbols, break them into lines no longer than 150 symbols. Don't describe the parameters of the class.

Make it shorter

Make this swift documentation shorter, but keep it meaningful

Follow best Swift documentation practices

Make this documentation to meet the requirements of the best Swift documentation practices