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

Curried versions of endswith and startswith #33193

Closed
carstenbauer opened this issue Sep 8, 2019 · 10 comments · Fixed by #35052
Closed

Curried versions of endswith and startswith #33193

carstenbauer opened this issue Sep 8, 2019 · 10 comments · Fixed by #35052
Labels
good first issue Indicates a good issue for first-time contributors to Julia status:help wanted Indicates that a maintainer wants help on an issue or pull request

Comments

@carstenbauer
Copy link
Member

carstenbauer commented Sep 8, 2019

In the spirit of #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 :)

@KristofferC
Copy link
Sponsor Member

KristofferC commented Sep 8, 2019

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 (#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.

@StefanKarpinski
Copy link
Sponsor Member

The criteria we agreed to when starting with that currying was:

  1. Two-argument function where the subject is the first argument: verb(subject, object).
  2. Currying on the second argument, so verb(object) = subject -> verb(subject, object).
  3. Linguistically, 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.

@o314
Copy link
Contributor

o314 commented Oct 13, 2019

#24990 is very high-level and new feature oriented. Not quite done yet.

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)

@oxinabox
Copy link
Contributor

oxinabox commented Mar 7, 2020

If we did #35031
And add contains as a Arg order flipped version of occursin
Then contains would have same pattern as needed.

@KristofferC
Copy link
Sponsor Member

I retract my comment at #33193 (comment), these specific set of functions do seem to fit the pattern where this would make sense.

@StefanKarpinski
Copy link
Sponsor Member

This seems decided: startswith & endswith are ok, occursin is not ok. Just needs a PR.

@StefanKarpinski StefanKarpinski added good first issue Indicates a good issue for first-time contributors to Julia status:help wanted Indicates that a maintainer wants help on an issue or pull request labels Mar 9, 2020
@StefanKarpinski StefanKarpinski changed the title Curried versions of endswith, startswith and occursin Curried versions of endswith, startswith ~and occursin~ Mar 9, 2020
@StefanKarpinski StefanKarpinski changed the title Curried versions of endswith, startswith ~and occursin~ Curried versions of endswith and startswith Mar 9, 2020
@carstenbauer
Copy link
Member Author

Just needs a PR.

Will create one.

@ptoche
Copy link
Contributor

ptoche commented Apr 22, 2021

I know this issue is closed and I don't mean to reopen it, but just a quick comment:

Works:

filter(f -> endswith(f, ".jl") && startswith(f, "test_"), readdir())

Doesn't:

filter(endswith(".jl") && startswith("test_"), readdir())
ERROR: LoadError: TypeError: non-boolean (Base.Fix2{typeof(endswith), String}) used in boolean context

Is it because it violates the criteria for currying in this case?

@carstenbauer
Copy link
Member Author

It doesn't work because you're trying to logically connect (&&) two objects of type Base.Fix2, which isn't defined.

@ptoche
Copy link
Contributor

ptoche commented Apr 23, 2021

I see. Thanks! Is there another operator, like a pipe, to connect two objects of type Base.Fix2?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Indicates a good issue for first-time contributors to Julia status:help wanted Indicates that a maintainer wants help on an issue or pull request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants