Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a macro-flag to run chain in global scope #37

Closed
wants to merge 2 commits into from

Conversation

pdeffebach
Copy link
Contributor

When debugging, it's often nice to be able to see intermediate inputs.

Because @chain operates inside a let block this is difficult. With this PR, you can add the macro-flag @outer at the top of your expression so that it isn't wrapped in a let block.

This way, variable assignments that happen inside @aside block can be worked with after the expression is done.

julia> @chain 1 @outer begin 
           +(2)
           @aside t = _
           *(5)
       end
15

julia> t
3

This PR is related to #33 .

I'm not wedded to the idea. I think there is room for more design thinking about how to make things inside @chain blocks interactive.

@jkrumbiegel
Copy link
Owner

We could also change the rules and say that any variable binding in @aside is exported. Or maybe an @export macro to put right where the assignment happens. Or we change the underlying block to begin end and allow @chain df let ... if one wants no variables to "leak out".

That is one of the drawbacks of this design I guess, that is not functionally encapsulated but creates these temporary variables. Ideally, one could treat the inside of the @chain like a normal begin end block, and not worry about the temporaries at all.

@pdeffebach
Copy link
Contributor Author

I think making let the default is still best. If we want users to use let, for performance and namespace reasons, then we shouldn't make the syntax more complicated.

@export would be good. I realized that the following fails

@chain df @outer begin 
    t = @transform ...
    @select ...
end

but if we had an @export call that I could put either as @export t = @transform ... or as @export t as a new line, that would be good.

Implementing it would be hard though. We could do something similar to @t and @astable where we build the syntax for a named tuple. Lets say

out, nt = let x1 = df
    x2 = f(x1)
    _nt_var = name = x2
    x3 = g(x2)
    
    nt = (name = _nt_var)
    x3, nt
end
(; nt)
out

@jkrumbiegel
Copy link
Owner

This was solved at some point. The let block was removed because I marked all the intermediates as local so they don't escape the begin end block. And you can use normal assignment syntax, don't even need @aside:

julia> @chain begin
           [1, 2, 3]
           sum
           d = _
       end
6

julia> d
6

julia> @macroexpand @chain begin
           [1, 2, 3]
           sum
           d = _
       end
quote
    #= REPL[52]:2 =#
    local var"##236" = [1, 2, 3]
    #= REPL[52]:3 =#
    local var"##237" = sum(var"##236")
    #= REPL[52]:4 =#
    local var"##238" = (d = var"##237")
    var"##238"
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants