DEV Community

Fernando Correa de Oliveira
Fernando Correa de Oliveira

Posted on

2

The Future of Red ORM for Raku

Introduction

Red is Raku’s object-relational mapper (ORM) – a library that lets you work with databases using Raku objects and classes instead of writing raw SQL. If you’ve been using Red, you know it’s built to be as Rakuish as possible, leveraging the language’s unique features to provide a seamless interface to your data. In this post, we’ll dive into the future of Red and what exciting changes lie ahead. We’ll briefly revisit what an ORM is, explore how Red currently builds queries from code blocks, and then look at how upcoming innovations—especially the advent of RakuAST—will empower a cleaner, more robust implementation.

What is an ORM (Object-Relational Mapper)?

Before we jump into the internals of Red, it helps to review what an ORM is and why you’d use one. An ORM connects the object world of your programming language with the table/row world of a relational database. In practice, this means:

  • Models as tables: You define classes (models) where each attribute corresponds to a database column, and each instance represents a row.
  • Abstracting SQL: Instead of writing SQL statements directly, you interact with the database through methods on your models. The ORM translates these operations into SQL queries.
  • Increased productivity: By working with Raku objects rather than raw SQL strings, you benefit from compile-time checks, type safety, and a more idiomatic programming style.

Many languages use ORMs (think ActiveRecord for Ruby or SQLAlchemy for Python). Red is Raku’s answer to this need, letting you write queries in a natural, expressive Raku style.

How Red builds queries today

Red’s design lets you write queries using ordinary Raku constructs. For example, suppose you have a model Post with attributes like title and published-at. You can filter posts with:

@posts.grep: {
    .title.starts-with("A")
    && .published-at >= DateTime.now.earlier: :6months
}
Enter fullscreen mode Exit fullscreen mode

Under the hood, when you call a method like .title on a model inside a query block, Red returns a proxy object representing the database column rather than a standard string. Operators (like >= or &&) are overloaded so that instead of computing a Boolean result immediately, they produce a Red AST node that represents the intended comparison. In other words, you’re not directly executing the condition but instead constructing a representation of it. When the query is eventually executed, Red’s driver translates that AST into SQL (for example, generating a WHERE clause).

This approach lets you write queries naturally and “Raku-ish” while allowing Red to handle the transformation into SQL behind the scenes.

Handling boolean context in query blocks

One of the more intricate challenges in Red’s implementation is understanding what a query block is intended to do. In Raku, code blocks are first-class objects but are completely opaque – they do not expose any information about the internal code, such as control flow constructs (e.g., if or unless). Red cannot inspect the block to see conditionals or operator usage. This opacity means that Red has no direct way to “read” the block’s logic.

To work around this limitation, Red employs a clever trick: it evaluates the query block under different Boolean contexts to infer its behavior. Essentially, Red observes when an AST node returned by the block is used in Boolean context. For example, consider this expression:

Post.^all.map: {
    .title || "Post id: { .id }"
}
Enter fullscreen mode Exit fullscreen mode

Since the block itself is opaque, Red cannot analyze the internal use of the || operator by inspecting the code. Instead, it notices that the left-hand side (i.e. .title) is used in a Boolean context. However, the block only returns an AST node without revealing its internal structure. To “guess” the intended behavior, Red runs the block twice: once treating the AST node as if it were Boolean True and once as if it were False. By doing so, it collects the outcomes corresponding to each context. With these results, Red can construct a mapping—typically a CASE expression in SQL—that reflects the intended logic:

SELECT
   CASE
      WHEN ( "post".title IS NOT NULL AND "post".title <> '' ) THEN "post".title
   ELSE 'Post id: ' || "post".id
   END as "data_1"
FROM "post"
Enter fullscreen mode Exit fullscreen mode

The key point is that because block objects do not expose their internal code, Red must resort to such “guessing” tactics. It relies solely on the behavior observed when an AST node is coerced into a Boolean value. This indirect method has worked but is inherently limited and complex.

The promise of RakuAST

This is exactly where RakuAST comes into play. Unlike block objects, the RakuAST representation of a block gives you full access to its internal structure. With RakuAST, Red will be able to directly inspect the entire syntax tree of a block—including conditionals, operator usage, and control flow constructs—without resorting to multiple evaluations or guessing.

In other words, while Red currently has to deduce a block’s intent by observing the outcomes of Boolean coercion, RakuAST will provide a transparent, detailed view of the block’s code. This means a direct translation from RakuAST nodes to Red’s internal AST and, ultimately, to SQL. The benefits are clear: fewer edge cases, clearer error messages, and a more maintainable codebase.

Enter RakuAST: A new hope for Red

You may have heard whispers about RakuAST—a project aimed at exposing a more structured and accessible Abstract Syntax Tree for Raku. In practical terms, RakuAST will allow module authors (like those working on Red) to directly inspect and manipulate the syntax tree of a code block. This is a game-changer for metaprogramming in Raku.

Why RakuAST Matters

Until now, Red has had to rely on creative (and sometimes convoluted) methods to capture the intent of user-supplied query blocks. Instead of having a straightforward way to inspect the code structure, Red depended on dynamic evaluation and clever Boolean coercions to build its internal AST. This indirect approach works, but it comes at the cost of complexity and potential fragility.

RakuAST promises to change that. With direct access to a structured representation of your code:

  • Direct AST parsing: Red can obtain the AST of a query block without executing it in a special “magic” mode. This means a direct translation from RakuAST nodes to Red’s internal AST.
  • Simplicity and robustness: Without having to rely on multiple evaluations to detect Boolean usage, the code that translates your query into SQL becomes much more straightforward. Red will simply walk the AST and generate the corresponding SQL expression.
  • Cleaner integration: Future enhancements—such as macros or additional syntax sugar—become more feasible when you can work with a proper AST. It opens the door for richer query syntax and better error messages when something goes wrong.

What will change in Red with RakuAST?

Once RakuAST is available in Rakudo, expect several improvements in Red:

  • Direct translation: Instead of “guessing” the structure of a block by observing its Boolean coercion, Red will directly translate a RakuAST node into its internal AST. For example, a function call like *.title.lc can be directly mapped to a Red::AST::Function node with a known function (such as LOWER), simplifying the translation.
  • Reduced complexity: The current hacks that force the block to run twice (to capture Boolean coercion outcomes) will be eliminated. This results in a more maintainable codebase and fewer edge cases.
  • Potential for new APIs: With a more robust internal representation, there’s room to introduce new API candidates. Imagine extending methods like .map and .grep to accept a named parameter like :raku-ast that directly supplies an AST node, giving users more control and clarity in how queries are constructed.

Benefits for Developers

For you, the end-user, these changes mean:

  • More predictable query behavior: With fewer “magical” side effects and a more direct AST translation, your queries will be more predictable.
  • Better error reporting: If there’s a problem with how your query is written, Red can analyze the AST and produce a more meaningful error message, pointing you directly to the issue.
  • Improved performance and maintainability: Eliminating the need for multiple evaluations reduces runtime overhead, while a simpler, more direct codebase encourages community contributions and faster evolution of the project.

Conclusion

Red has always aimed to make database interactions feel natural in Raku—using objects, methods, and familiar operators to create expressive queries. Today, Red relies on a workaround approach that deduces the behavior of query blocks by evaluating them under different Boolean contexts, simply because Raku’s block objects do not reveal their internal structure. This necessitates multiple evaluations and clever tricks to “guess” the intended logic.

The introduction of RakuAST will fundamentally change this landscape. With direct access to a block’s syntax tree, Red can read every detail—conditionals, operator usage, and control flow—eliminating the need for guesswork. This evolution will result in cleaner, more robust query generation, clearer error messages, and a codebase that’s easier to maintain and extend.

For experienced Raku developers, these changes mark an exciting step forward. Red’s future is bright, and its evolution in tandem with the advancements in Raku itself promises to make it even more powerful and intuitive. Whether you’re writing simple queries or constructing complex dynamic conditions, the coming improvements will enhance your productivity and confidence.

Happy coding with Red—here’s to a more transparent and Raku-ish future!

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • 0:56 --last-failed
  • 2:34 --only-changed
  • 4:27 --repeat-each
  • 5:15 --forbid-only
  • 5:51 --ui --headed --workers 1

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Click on any timestamp above to jump directly to that section in the tutorial!

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

DEV shines when you're signed in, unlocking a customized experience with features like dark mode!

Okay