Skip to content

Exploring Non Panic Short-Circuit Control Flow #89

@taman9333

Description

@taman9333

This issue aims to open a focused discussion on implementing an efficient, non-panic short-circuit control flow

Context: Performance and Previous Work

We previously implemented a form of Do-notation which works as expected. However after running performance benchmarks I found that relying on panic to implement the short-circuit/error control flow is inefficient when dealing with a high frequency of unsuccessful paths

This challenge was briefly touched upon in #78 where I added some comments asking about that using sequencing, but since that PR is now merged and the topic is distinct, I thought it better to open a new issue for a focused discussion.


The Problem: Dynamic Operator Composition and Control Flow

In your last comment here, you mentioned the upcoming reactive programming library, providing an example of a pipe-based observable chain. While this structure is clean, it highlights a potential limitation related to the problem of short-circuiting:

What if I need my operators to have varying arities and different types of those arities, or even variadic generics?

The typical observable pipe constrains each operator to a single, specific input and output type (T -> T').
For example, my use case might require:

  • An operator that takes a string and returns a User struct.
  • A subsequent operator that takes both User and a DatabaseConnection to save the record.

Achieving this kind of dynamic typing and varying arity within a type-safe pipeline in Go, while also supporting short-circuiting, is extremely challenging without relying on something like panic as I mentioned before.


In other non-functional languages, efficient short-circuiting is often enabled by features that support cooperative execution control:

  • Node.js: Uses Generators (yield), allowing the consumer to pause and resume the producer.
  • Ruby: Uses Enumerators for explicit, outside control over execution flow via yield and resume

I believe Go’s current language semantics lacking this outside control flow, I'd be very interested if you have any idea in your mind for resolving this short-circuiting/control-flow problem

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions