This is a long story and ideas/PRs have been proposed (eg. #24990), but it seems still unclear when and if such a syntax will be implemented. Combining command literals with few functions from Underscores.jl and I got a simple prototype.
julia> using Underscores: replace_
julia> import Base: @cmd
julia> macro cmd(str)
replace_(Meta.parse(str))
end
@cmd (macro with 1 method)
Thereafter `_[2]` becomes x -> x[2] and `_1 + _2` results in (x,y) -> x + y.
julia> using DataFrames, Chain
julia> df = DataFrame(x = [1, 3, 2, 1], y = 1:4);
julia> @chain df begin
filter(`_.x > 1 && isodd(_.y)`, _)
transform([:x, :y] => ByRow(`_1 *100 + _2`) => :z)
end
1Ă—3 DataFrame
Row │ x y z
│ Int64 Int64 Int64
─────┼─────────────────────
1 │ 2 3 203
However we should define a macro , say @sh_cmd, for the original Base.@cmd, which produces a Cmd. How to do it in a clean way?
Also, is it worth putting this into Base or another package? Thanks.
Edit: after thinking twice, I’d like to propose f` ` instead, i.e., just define @f_cmd, whose difference with ` ` to my use case for curring underscore is negligible.
Command literals are already widely used, and such a fundamental change would break a ton of libraries if it were introduced into Base. The earliest it could be incorporated would be v2.0, and that seems very unlikely given the existence of several packages that do the same thing without requiring breaking changes. You’re welcome to create a package that provides this macro, and your creativity is appreciated, but you’ll be facing some stiff headwinds by pirating @cmd.
This is a good idea, but the piracy makes it unlikely to work out. There’s always the possibility to do @f_str or something, but it’s a bit unfortunate that it breaks things like syntax highlighting.
Thanks for your reply and I thought twice and changed the original post.
Also, I prefer @f_cmd to @f_str because of the pairing thing, e.g. f"startswith("Julia", _)".
@qsong is proposing a command macro f`...` instead of a string macro f"...". Both work the same (see the documentation) and this seems like a reasonable use of a command macro: a function is conceptually close to a command?
which we already have support for? Adding syntax is usually a tradeoff about increasing the complexity of the language (by some amount) in order to make something more convenient (by some amount), so I’d like to understand both sides of the tradeoff in this case.
Hm, this is strange. One should be able to locally shadow @cmd in your module so you don’t have to pirate Base.@cmd, but that’s not happening for me.
julia> using Underscores: replace_
julia> macro cmd(str)
replace_(Meta.parse(str))
end
@cmd (macro with 1 method)
julia> @which `_[2]`
var"@cmd"(__source__::LineNumberNode, __module__::Module, str) in Base at cmd.jl:426
julia> @which @cmd "_[2]"
var"@cmd"(__source__::LineNumberNode, __module__::Module, str) in Main at REPL[2]:1
Does anyone know why this is happening?
I guess @cmd has more special sauce baked in than I realized.
I don’t understand your point: we already have as much support for fn`a + b` as for fn"a + b" : in both cases you just need to define a macro (fn_cmd or fn_str).
The following already works without adding new language features, you can try it:
julia> using Underscores: replace_
julia> macro fn_cmd(str) replace_(Meta.parse(str)) end
@fn_cmd (macro with 1 method)
julia> map(fn`_[2]`, [(1,2,3,4), (10,20,30,40)])
2-element Vector{Int64}:
2
20
I’d never before heard of command macros outside the context of creating shell commands. So seeing something like
I would assume it was somehow interacting with the shell. A quick search doesn’t tell me much about command macros. So why would it be a better choice here than a string macro?
Also, I they are awkward to type into discourse: fn`a+b` (this almost works.)
Yeah non-standard command literals are probably a little known feature of the language (which is no reason not to use it).
To defend its use here: I would find a string at least as strange: writing Julia code in a string (in a Julia program) really rubs me the wrong way.
But looking at the bigger picture, I think both string and command literals are the wrong solutions to the “curry” problem. I think the simple approach implemented in this PR is an excellent solution (and that it’s actually a good thing that a macro like @_ is required more complicated cases). I hope it gets adopted…
Thanks for your replies. I guess currying underscore is like keyboard shortcut. I mean some people use it on daily basis while others might not. I have read the long discussion about the PR #24990 and it seems not the solution to Admins. Last December another idea proposed.
There are some issues when I try to use Chain.jl and Underscore.jl simultaneously. I hope this simple command literals f` ` would be helpful for others when prototyping.
I am not sure about this, I think that it is the favored solution in the long run, but some corner cases need to be hashed out first and there is no particular urgency about it.
Personally, I like that core devs are cautious and circumspect about adding new syntax. Any extension to Julia will be with us for a long time, so it is important to get it right.