Logo

dev-resources.site

for different kinds of informations.

In Theory: Self-Correcting Software - Part 2

Published at
9/7/2024
Categories
eventdriven
ai
programming
refactoring
Author
ingigauti
Author
9 person written this
ingigauti
open
In Theory: Self-Correcting Software - Part 2

This article explores Plang, an intent-based programming language designed to interpret natural language. For more information, visit plang.is or take your first steps

In a previous article on self-correcting software, I demonstrated how Plang code can self-correct. It was a simple proof of concept, but let's dive deeper into how this works.

How Plang Works

Plang compiles into JSON files—essentially instructions—that are saved into a .pr file. This .pr file tells the Plang runtime how to execute your code. Keep this .pr file in mind as it plays a crucial role in what follows.

Example of a Basic Instruction:

- read file.txt to %content%
Enter fullscreen mode Exit fullscreen mode

This would generate a JSON instruction like so:

{
    "ModuleType":"FileModule",
    "FunctionName": "ReadTextFile",
    "Parameters": [{"path": "file.txt"}]
}
Enter fullscreen mode Exit fullscreen mode

The Plang runtime will load the appropriate FileModule, and if you examine the Program.cs file, you'll find a method called ReadTextFile.

This is where Plang is currently at, in version 0.1.

The Challenge: Refactoring and Compatibility

Now, imagine we want to refactor the method name from ReadTextFile to ReadContentOfTextFile in the Program.cs.

Any Plang code that uses the old method name(ReadTextFile) will break and throw an error like this:

Error:
    Message: Method 'ReadTextFile' could not be found. 'ReadTextFile' is defined in your instruction file
    Key: MissingMethod
Enter fullscreen mode Exit fullscreen mode

In the previous article, I showed how Plang can bind events to goals (functions) or steps (lines of code). We’ll use this feature to handle method refactoring gracefully.

Self-Correcting Code in Action

We start by creating an event listener that catches this specific error:

Events
- on any error where key="MissingMethod", call FixCode
Enter fullscreen mode Exit fullscreen mode

Step 1: Collect Available Methods

First create FixCode.goal and give it the title

FixCode
Enter fullscreen mode Exit fullscreen mode

Next, we want to resolve the MissingMethod error by finding the updated method in the FileModule.

We need to gather all available methods in FileModule. We can access what module caused the error from the %!step.ModuleType% property:

- get all available methods in %!step.ModuleType%, write to %methods%
Enter fullscreen mode Exit fullscreen mode

ProTip: In Plang, the %!step% variable always contains the current step running, including its ModuleType, which points to the FileModule. If you want to know what properties are in %!step%, just write it out - write out %!step%

This will include methods like ReadContentOfTextFile. Here's an example of what it might look like:

[
  {
    "Method": "public async Task<string> ReadContentOfTextFile(string path, string returnValueIfFileNotExisting = '', bool throwErrorOnNotFound = false, bool loadVariables = false, bool emptyVariableIfNotFound = false, string encoding = 'utf-8')",
    "Description": "Read the content from a file. Formerly ReadTextFile"
  },
  {
    "Method": "public async Task WriteToFile(string path, string content, bool overwrite = false, bool loadVariables = false, bool emptyVariableIfNotFound = false, string encoding = 'utf-8')",
    "Description": "Write content to a file"
  }
  ...
  ...
  ...
]
Enter fullscreen mode Exit fullscreen mode

Step 2: Read the Failing Instruction

Next, we read the instruction .pr file for the step that triggered the error:

- read %!step.AbsolutePrPath%, into %instructions%
Enter fullscreen mode Exit fullscreen mode

AbsolutePrPath is a property of the %!step% variable that points to the location of the .pr file on your hard drive

Step 3: Call the LLM to Fix the Code

We can now pass the problem to a language model (LLM) to update the method name:

- [llm] system: The user is attempting to execute code, but the method was not found, possibly due to renaming.
              These are the instructions to call the C# code: %instructions%
              These are the available methods: %methods%
              Rewrite the instructions
      user: %!error.Message%
      scheme: {instructions:string}
Enter fullscreen mode Exit fullscreen mode

With this input, the LLM can generate the corrected code and return it in the %instructions% variable.

Step 4: Write the Corrected Code

Finally, we overwrite the .pr file with the corrected code and re-execute the step:

- write %instructions% to %!step.AbsolutePrPath%
- retry step
Enter fullscreen mode Exit fullscreen mode

Final Solution:

The complete self-correcting code looks like this:

FixCode
- get all available methods in %!error.ModuleType%, write to %methods%
- read %!step.AbsolutePrPath%, into %instructions%
- [llm] system: The user is attempting to execute code, but the method was not found, possibly due to renaming.
              These are the instructions to call the C# code: %instructions%
              These are the available methods: %methods%
              Rewrite the instructions
      user: %!error.Message%
      scheme: {instructions:string}
- write %instructions% to %!step.AbsolutePrPath%
- retry step
Enter fullscreen mode Exit fullscreen mode

In-Theory Article

This is still theoretical—these modules aren't yet available in Plang, and some features like retry step and get all available methods aren't implemented. But once the language matures, this will work.

So why haven’t I implemented this yet? Well, Plang is evolving fast, and there are a thousand things to work on. But I wanted to outline this approach first.

Plang's Upgrade Path

This opens up a fascinating upgrade path for Plang. Since Plang is still in its early stages, breaking changes are common. This approach would allow upgrades to happen almost automatically, minimizing the need for manual fixes.

Of course, there's still a lot of engineering ahead, but the conceptual problem is solved.

Extending Plang with Modules

It's easy to extend Plang using modules. For example, to interact with Google Drive, you could install the Google.Drive module:

Start
- get list of all my files in "tAff2u44jU2nZgpJkbY5mSwW3" on Google Drive, %files%
- write out "List of all files: %files%"
- go through %files%, call ProcessFile

ProcessFile
- download file from Google Drive, fileId=%item.id%, save it to file/%item.name%
Enter fullscreen mode Exit fullscreen mode

Now imagine the module developer updates the API and renames methods. Thanks to our self-correcting system, your code would still work without any changes on your end.

A Word of Caution

As programmers, we’re naturally skeptical about automated fixes happening without confirmation. This is where unit tests come into play. But that’s a topic for another article.

More Information

Interested in learning more about Plang? Here are some useful resources to get started:

refactoring Article's
30 articles in total
Favicon
Python: Refactoring to Patterns
Favicon
STOP Writing Dirty Code: Fix The Data Class Code Smell Now!
Favicon
7 Ways to Refactor Your Flutter Application
Favicon
Những Tip đơn giản giúp đoạn code trở nên CLEAR và MAINTAIN dễ hơn
Favicon
Refactoring 021 - Remove Dead Code
Favicon
React v19, unboxing! 📦
Favicon
De software legacy a oportunitat estratègica: El punt de partida (I)
Favicon
The Backend Testing Breakup 💔
Favicon
Simplifying your code: replacing heavy packages with lightweight solutions
Favicon
The Rewrite Trap: A Programmer's Survival Guide
Favicon
Refactoring: The Art of Polishing Code
Favicon
El verdadero valor del software no siempre está en el presente
Favicon
Refactoring 019 - Reify Email Addresses
Favicon
How LLMs Revolutionize Coding Efficiency
Favicon
Effective Strategies for Refactoring a Large Codebase: Best Practices and Approaches
Favicon
Convert a ReactJS app from Vite to Nx
Favicon
Simplifying Conditional Expressions in C#: Tips for Clean and Readable Code
Favicon
Simplifying Method Calls in C#: Techniques for Cleaner and More Maintainable Code
Favicon
Mastering Clean Code: 4 Essential Techniques for Organizing Data in C#
Favicon
Refactoring: Moving Features Between Objects
Favicon
Composing Methods: A Practical Guide to Clean Code
Favicon
Refactoring 017 - Convert Attributes to Sets
Favicon
Como Refatorar Seu Código Com Muitos If-Else? Part 2
Favicon
Stop Re-Implementing Code: Use Extract Method in Rust
Favicon
De lo funcional hasta lo legible con Tidyings
Favicon
The Double-Edged Sword of IEnumerable and yield return in C#
Favicon
In Theory: Self-Correcting Software - Part 2
Favicon
Make your package.json readable again by humans: organizing npm scripts with shell files
Favicon
Transforming DevEx Through Bulk Refactoring (and How AI Can Assist)
Favicon
Refactoring for Efficiency: Tackling Performance Issues in Data-Heavy Pages

Featured ones: