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

change match arg order to match contains? #25584

Closed
StefanKarpinski opened this issue Jan 16, 2018 · 18 comments
Closed

change match arg order to match contains? #25584

StefanKarpinski opened this issue Jan 16, 2018 · 18 comments
Labels
domain:strings "Strings!"

Comments

@StefanKarpinski
Copy link
Sponsor Member

Having used it for a bit, I don't mind contains(string, regex) but the fact that contains(string, regex) gets used a lot together with match(regex, string) and they have different argument order is really a bummer. Perhaps we should change match and similar functions to take arguments in the other order? Since one of the arguments is a regex object, we could really support either order.

@StefanKarpinski StefanKarpinski added domain:strings "Strings!" status:triage This should be discussed on a triage call labels Jan 16, 2018
@KristofferC
Copy link
Sponsor Member

This seems to make sense to me. A string contains a regex but a regex matches a string.

@StefanKarpinski
Copy link
Sponsor Member Author

StefanKarpinski commented Jan 16, 2018

I know, it makes sense by the verb(subject, object) convention, but it's just really annoying switching back and forth between the two orders for example, in this code:

julia/base/loading.jl

Lines 471 to 489 in 1c499c7

if contains(line, re_array_of_tables)
uuid == where && break
uuid = deps = nothing
state = :stanza
elseif state == :stanza
if (m = match(re_uuid_to_string, line)) != nothing
uuid = UUID(m.captures[1])
elseif (m = match(re_deps_to_any, line)) != nothing
deps = String(m.captures[1])
elseif contains(line, re_subsection_deps)
state = :deps
elseif contains(line, re_section)
state = :other
end
elseif state == :deps && uuid == where
if (m = match(re_key_to_string, line)) != nothing
m.captures[1] == name && return UUID(m.captures[2])
end
end

You can also say that a string matches a regex rather than that a regex matches a string, so the other order is linguistically justifiable as well.

@malmaud
Copy link
Contributor

malmaud commented Jan 16, 2018

I've been bugged by the inconsistent order too.

@nalimilan
Copy link
Member

nalimilan commented Jan 16, 2018

It's inconsistent with all find* functions too, so I'd rather change contains to use the same rule as other functions than match. The only justification for the current argument order of contains is that it could read as an infix operator (c contains y), but since it's not an operator...

The problem is that we cannot switch arguments for contains(::String, ::String) with a deprecation. I guess we could provide a temporary replacement in 0.7, and reintroduce the method with reversed arguments in 1.0.

@StefanKarpinski
Copy link
Sponsor Member Author

I guess we need a "contained in" operator.

@simonbyrne
Copy link
Contributor

cf #19250

@simonbyrne
Copy link
Contributor

I guess we need a "contained in" operator.

\isinE    \isindot   \isinobar  \isins     \isinvb

Pick one?

@KristofferC
Copy link
Sponsor Member

Just put back ismatch...?

@nalimilan
Copy link
Member

Or maybe we don't need this at all, and isempty(findfirst(needle, haystack)) is enough?

OTOH #24303 gives a possible reason why we would want to have a dedicated function/operator (tentatively called issubseq there): to check in a generic way whether any collection contains a sequence of elements (and not only for strings). I suggested to do this via something like findfirst(sequence(needle), haystack), but I'm not against having an operator.

@StefanKarpinski
Copy link
Sponsor Member Author

We need something that actually returns the RegexMatch object, not just whether something matched, so we can't really get rid of match here. We could also support both argument orders.

@nalimilan
Copy link
Member

I don't think anybody suggested getting rid of match. contains is the only outlier here vs. find* and match.

@JeffBezanson
Copy link
Sponsor Member

The argument order "x contains y" makes too much sense to me to change. It can be understood by anybody who knows english, while the other argument order requires you to know the convention used by find functions.

@JeffBezanson
Copy link
Sponsor Member

But if we renamed it or added e.g. findsubseq or containedin then the argument order could be changed.

@simonbyrne
Copy link
Contributor

We do the opposite for collections, i.e. "x in y".

@StefanKarpinski
Copy link
Sponsor Member Author

StefanKarpinski commented Jan 19, 2018

x in y tests whether x is in y...

@simonbyrne
Copy link
Contributor

Yes, my point was that the smaller element (x) comes first. So it would make sense that in matching, the pattern which your looking for should also come first.

@StefanKarpinski
Copy link
Sponsor Member Author

We can always add a function that's like contains but with the reverse argument order, e.g. contained(needle, haystack) or within(needle, haystack) but that can be done at any point.

@felixcremer
Copy link
Contributor

This is closed in #26283 where contains is deprecated to occursin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:strings "Strings!"
Projects
None yet
Development

No branches or pull requests

7 participants