codedthinking / Kezdi.jl

Julia package for data manipulation and analysis
https://codedthinking.github.io/Kezdi.jl/
Other
18 stars 0 forks source link

Design Multichannel piping #10

Closed korenmiklos closed 1 month ago

korenmiklos commented 4 months ago

https://chat.openai.com/share/3483a909-74bb-432d-9a72-f3f01ef472c5

korenmiklos commented 4 months ago

Yes, you can combine the setup, operation chain, and teardown into one step using a do...end block or by creating a custom macro. Below are examples of both approaches.

Using do...end Block

You can define a function that takes a block of operations to perform within a managed environment. Here's how you might do that:

function with_environment(f::Function)
    env = setup_environment()  # Setup environment
    try
        f(env)  # Execute the passed-in block of code
    finally
        teardown_environment(env)  # Ensure environment is torn down even if an error occurs
    end
end

# Usage
with_environment() do env
    @chain begin
        start_with(env)
        command1(_, arg1, arg2)  # Assume command1(env, arg1, arg2)
        command2(arg1, _)        # Assume command2(arg1, env)
        command3                 # Assume command3(env)
    end
end

In this example, setup_environment and teardown_environment would be replaced with your actual setup and teardown functions, and the commands and arguments within the @chain block should be replaced with your actual processing logic.

Creating a Custom Macro

If you want to encapsulate the pattern even further, you could define a custom macro. Here's a basic example:

macro with_environment(body)
    return quote
        env = setup_environment()  # Setup
        try
            @chain begin
                $(esc(body))
            end
        finally
            teardown_environment(env)  # Teardown
        end
    end
end

# Usage
@with_environment begin
    start_with(env)
    command1(_, arg1, arg2)
    command2(arg1, _)
    command3
end

In this macro:

Both of these approaches allow you to neatly encapsulate the pattern of setting up an environment, performing a series of operations, and then tearing down the environment, similar to context management in other programming languages. Choose the approach that best fits your coding style and the complexity of your use case.

korenmiklos commented 2 months ago

We need a proper treatment of @aside, not a multichannel pipe.

I would introduce our own @chain macro, called @with, say, that includes the following features:

@with df env(STATA) globals(n_cutoff, tolerance) begin
    @keep @if n_users >= n_cutoff
    @replace output = round(output + tolerance) @if output == 0
end 
korenmiklos commented 1 month ago

Let blocks are better for this:

https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Let-Blocks