DEV Community

Cover image for Probabilistic vs. Deterministic: Choosing the Right Code Generator.
Jorge Carracedo
Jorge Carracedo

Posted on

Probabilistic vs. Deterministic: Choosing the Right Code Generator.

async function isOdd(n) {
     const response = await chatGpt("Is the number ${n} odd? Answer only YES or NO"); 
    return response === "YES"; 
}
Enter fullscreen mode Exit fullscreen mode

For some time now, a certain type of joke has been circulating on social media where an LLM is used to determine whether a number is even or odd. The multidisciplinary nature of these models, which, by the way, are incredible, allows them to be used to solve all kinds of problems; however, it is necessary to ask whether their use is appropriate in every situation. In cases like this, it is obvious that the solution is incorrect: it isn't guaranteed to work 100% of the time, and it is certainly not efficient. Nevertheless, in other scenarios, it is not always clear whether using an LLM is the optimal solution.

When we focus on the use of language models for application development, the trend is clear: the use of LLM-assisted code generation is becoming the standard, not just for sporadic development but integrated into engineering processes and top-tier corporate environments. It is precisely in these cases where asking, "Am I applying the optimal solution?" becomes most valuable.

The alternative is not new; we have had code generation tools for many years, such as template-based or model-based generators. These are declarative generation tools. Their most relevant functional characteristic is their deterministic nature: given a specific input, they always produce the same result. This is a highly valued trait in software development as it ensures reliability in the generated code. Their main advantages are significantly lower costs and higher performance compared to an LLM. On the other hand, these tools are incapable of improvising; they cannot provide solutions that haven't been previously defined.

In short, we have two code generation tools, LLMs and declarative generators, each with its own pros and cons.

However, not all code in an application is the same. To simplify, we can distinguish between two categories: structural code, which defines the application's foundation (including integration components, configurations, and other common artifacts), and business logic code.

The former, structural code, is distinct because it is predictable, maintains a homogeneous and well-defined structure, and usually accounts for a larger percentage of the total codebase. This code is ideal for declarative generation tools, offering low-cost and high reliability.

On the other hand, business logic code is application-specific and unpredictable. This type of code is impossible to cover with declarative generators; however, language model-based generators can produce it successfully.

Combining both types of generation tools to cover an entire application creates a synergy. The output of the LLM is reinforced because its scope is narrowed, and it is fueled by the context provided by the structural code created by declarative tools.

Reducing the scope of the non-deterministic component leads to a result that is generally more reliable, secure, and potentially less prone to errors. The question I leave on the table is whether, with the rise of AI, we are casting aside the elegance of deterministic generation solutions.

Top comments (0)