In the spirit of https://github.com/JuliaLang/julia/pull/30915 I was wondering whether a PR for adding single-argument versions of endswith
, startswith
, and occursin
that can be used as follows in functions like filter
would be appreciated.
filter(endswith(".jl"), readdir())
I feel that I have definitely typed x->endswith(x, ".jl")
far too often :)
Having a long list of functions where the first argument is considered special seems bad to me. Instead, just like with vectorized function we should IMO focus on syntax that tries to handle all of this in one fell swoop (https://github.com/JuliaLang/julia/pull/24990). Anything else will just be a neverending debate of what functions should implement this special handling and since Base code is not special, this will also seep out to the package ecosystem. We should learn from the f(::Missing) = missing
story that is currently experiencing that thing and not try have another of those situations.
The criteria we agreed to when starting with that currying was:
verb(subject, object)
.verb(object) = subject -> verb(subject, object)
.verb(object)
reads naturally as a predicate.These criteria are clearly met by endswith
and startswith
:
endswith(".jl")
is a predicate for strings that end with .jl
startswith("/")
is a predicate for strings for start with /
.For occursin
it's more borderline since by these rules, occursin(object)
is a predicate that applies to patterns (subject
) to test whether they occur within a fixed collection or string (object
). That's probably not what you had in mind. If we had the ismatch(string, pattern)
predicate of yore, then ismatch(pattern)
would do what you want.
One could simply generate a lot of those binding (currently defined in https://github.com/JuliaLang/julia/blob/v1.2.0/base/operators.jl with a for
loop doing @eval
over a preset array of function names. Rather simple.
There will be however some corner cases with builtins functions such as
@test_throws ErrorException Base.:(===)(t) = Base.Fix2(:(===),t)
@test_throws ErrorException Base.isa(t) = Base.Fix2(isa,t)
@test_throws ErrorException Base.:(<:)(t) = Base.Fix2(:(<:),t)
If we did https://github.com/JuliaLang/julia/issues/35031
And add contains
as a Arg order flipped version of occursin
Then contains
would have same pattern as needed.
I retract my comment at https://github.com/JuliaLang/julia/issues/33193#issuecomment-529205329, these specific set of functions do seem to fit the pattern where this would make sense.
This seems decided: startswith
& endswith
are ok, occursin
is not ok. Just needs a PR.
Just needs a PR.
Will create one.
Most helpful comment
Having a long list of functions where the first argument is considered special seems bad to me. Instead, just like with vectorized function we should IMO focus on syntax that tries to handle all of this in one fell swoop (https://github.com/JuliaLang/julia/pull/24990). Anything else will just be a neverending debate of what functions should implement this special handling and since Base code is not special, this will also seep out to the package ecosystem. We should learn from the
f(::Missing) = missing
story that is currently experiencing that thing and not try have another of those situations.