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

Feature Request: if no __ is specified then insert into first argument #17

Open
xiaodaigh opened this issue Aug 15, 2020 · 9 comments
Open

Comments

@xiaodaigh
Copy link

xiaodaigh commented Aug 15, 2020

Currently

@_ a |> f(_, b) is needed but in other tools like Lazy.jl and R's magrittr which allows the first argument to be the previous one without _ e.g.

@_ a |> f(b) would be equivalent to f(a,b) and @_ a |> f(_, b)

@mcabbott
Copy link
Collaborator

mcabbott commented Aug 15, 2020

I think being explicit is a virtue of this package. Automatically inserting __ as the first (or should it be last?) argument would also make it impossible to chain functions which do already return a closure:

g(x) = begin y=exp(x); z -> z .* y end
@_ data |> filter(abs(_)>1, __) |> g(x) |> scatter

(Note that @_ a |> f(_, b) means a |> f(identity, b), but I assume you meant @_ a |> f(__, b) with two underscores.)

@xiaodaigh
Copy link
Author

Interesting argument. But g(x)() would work. And also it's more often the case that we need _ as first argument then it is to get a closure as return from a function.

@mcabbott
Copy link
Collaborator

mcabbott commented Aug 15, 2020

Ah right, there's a way... and I guess |> g(x)(__) |> scatter would likewise be the most explicit way to write my example today.

Do you have examples of where you'd want first rather than last-argument __? The tests have many map / sum / filter (last) and one sort (only).

@xiaodaigh
Copy link
Author

The way that Lazy.jl deals with it is that

@> and @>> are for first and last. Perhaps @_ will optionally allow _ anywhere and also have a @_last macro?

Also

@_ obj begin
  function1
  function2
  function3
end

without needing |> would be nice.

@c42f
Copy link
Owner

c42f commented Aug 27, 2020

Overall I think this is an interesting idea, and might resolve some of the uglyness of __. I think the rule might be:

  • For Expr(:call) on the right hand side of an |> expression, if __ doesn't appear in the call, insert it as the last argument.

Thus, we'd have the following work:

@_ data |> filter(abs(_)>1) |> map(_+1) |> scatter

If there's no piping present, no __ would be inserted.

The need to explicitly use __ for use with functions-which-return-functions is unfortunate, however, and would make Underscores.jl unattractive for use with libraries which are designed with currying in mind. @tkf — that's probably your case case?

Another option could be to... just add more underscores, and have a macro @__ which does this transformation, leaving @_ as it is?


It's worth keeping in mind that this package is not just about pipelines, though that's one of the nice use cases for it (I think where you mention _ above, you really mean __.)

without needing |> would be nice.

Personally I don't like the implicit chaining syntax in Lazy.jl at all so I'd rather not emulate it!

@tkf
Copy link

tkf commented Aug 27, 2020

Yeah, transducers are always "curried". So, we'd need extra () like @_ collection |> Filter(abs(_) > 1)() |> sum if __ is automatically inserted.

@c42f
Copy link
Owner

c42f commented Sep 3, 2020

@xiaodaigh I still think this is a good idea; we'd just need to modify it a little.

What if we implemented a @__ macro which followed the rule I laid out in #17 (comment) ? Would that serve your use case?

@c42f c42f reopened this Sep 3, 2020
@tkf
Copy link

tkf commented Sep 6, 2020

A bit crazy idea is to use some infix combinator like

julia> f $ args::Tuple = x -> f(args..., x)
       f $ a = x -> f(a, x)
$ (generic function with 2 methods)

julia> @_ -3:3 |> filter$(abs(_)>1) |> map$(_+1) |> collect
4-element Array{Int64,1}:
 -2
 -1
  3
  4

Though it's not ideal that f$(x) may or may not splat x when its type is unknown. You'd have to write f$(x,) or f$(x...,) to be very specific.

@c42f
Copy link
Owner

c42f commented Sep 9, 2020

I've found a couple of uses of @_ in the last few weeks while where having __ as the last parameter wouldn't work. For example

@_ read(`git status --porcelain`) |> String |> split(__,'\n')

@c42f c42f changed the title Feature Request: if no _ is specified then insert into first argument Feature Request: if no __ is specified then insert into first argument Jul 6, 2021
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

No branches or pull requests

4 participants