Given that the args of tools:::%notin% don’t match %in% I'd say it was just a 
local use more than any deep thought about general use. 

Personally, I really like the idea of %notin% because it is very often that you 
start typing foo[foo %in% and then realise you want to invert it and the 
preceding negation is then cognitively sort of in the wrong place (reads like 
"not foo"). I also like %notin% better than %!in% because I think a salad of 
special characters makes things harder to read, but that may be just subjective.

And to your 'why bother' question - I do think it’s better to standardise 
common operators in core rather than have packages re-define it each time. And 
certainly just importing something that trivial from another package is a bad 
idea given the dependency implications. (On the flip side: if you start using 
it you need to depend on recent R which may not be feasible in some 
environments, but then if that was always the argument we’d never add anything 
new :P).

Cheers,
Simon


> On 28 Nov 2025, at 08:24, Duncan Murdoch <[email protected]> wrote:
> 
> On 2025-11-27 11:58 a.m., Marcelo Ventura Freire wrote:
>> If it is not a rhetorical question about a closed issue (if it is, tell me 
>> and I will shut up), this inclusion [1] would be useful (since it was 
>> exported and rewritten so many times by so many people and will keep being), 
>> [2] would create an uniformization (since it was and will be written under 
>> so many names before), [3] would not break stuff (since it is not altering 
>> the interface of any already existing function nor it is overwriting any 
>> symbol with a diverse use), [4] would not be neither a complex nor a 
>> tiringsome inclusion (even I myself could do it in a single 1-line pull 
>> request, hypothetically speaking) and [5] would benefit users all around.
>> I am not naive to the point of believing that an alteration to the R core 
>> would have few repercussions and surely there must be reasons why it was not 
>> done before.
> 
> I don't know why it was added to tools but not exported, but here is my guess:
> 
> - A member of R Core agrees with you that this operator is useful. This 
> appears to have happened in 2016 based on the svn log.
> - It already existed in some contributed package, but base packages can't 
> import anything from non-base packages, so it needed to be added.
> - It wasn't exported, because that would break some packages:
>    - the ones that export something with that name would now receive a check 
> message about the conflict.
>    - if those packages stopped exporting it, then any package that imported 
> from one of them would have to stop doing that, and import it from the base 
> package instead.
> - It is very easy to write your own, or to import one of the existing ones, 
> so a lot of work would have been generated for not very much benefit.
> 
> R Core members try to be careful not to generate work for others unless 
> there's enough of a net benefit to the community.  They are very busy, and 
> many authors of contributed packages who might be affected by this change are 
> busy too.
> 
> 
>> But, in the end, this inclusion would be just a seemingly unharmful syntax 
>> sugar that could be shared, like it was with "\" for the reserved word 
>> "function", but with waaaay less work to implement.
> 
> The difference there is that it added new syntax, so as far as I know, it 
> didn't affect any existing package.  Personally I don't see that it really 
> offered much of a benefit (keystrokes are cheap), but lots of people are 
> using it, so I guess some others would disagree.>
>> If it is not a dumb proposal, I can just include it in the wishlist of 
>> features in Bugzilla as prescribed in the contributor's page or I can do 
>> that PR myself (if you propose more work to others, the sensible thing to do 
>> is at least to offer yourself to do it, right?). In either case, I create 
>> more work to the dev team, perhaps to different people.
> 
> It's hard for you to do the coordination work with all the existing packages 
> that use a similar operator, so I don't think that's really feasible.
> 
>> Thanks for taking your time to answer me.
> 
> No problem.  I'm sitting in an airport waiting for a plane, so any 
> distraction is a net benefit for me!
> 
> Duncan Murdoch>
>> Marcelo Ventura Freire
>> Escola de Artes, Ciências e Humanidades
>> Universidade de São Paulo
>> Av. Arlindo Bettio, 1000,
>> Sala Paulo Freire (Sala Coletiva 252), Prédio I1
>> Ermelino Matarazzo, São Paulo, SP, Brasil
>> CEP 03828-000
>> Tel.: (11) 3091-8894
>> Em qui., 27 de nov. de 2025 às 14:15, Duncan Murdoch 
>> <[email protected] <mailto:[email protected]>> escreveu:
>>    The R sources already contain an operator like that, though it is not
>>    exported.  tools:::`%notin%` is defined as
>>       function (x, y)
>>    is.na <http://is.na>(match(x, y))
>>    Several CRAN packages export a similar function, e.g. omnibus, mefa4,
>>    data.table, hutils, etc. So I think if it was exported by R that's a
>>    better name, but since it is easy to write yourself or import from some
>>    other package, why bother?
>>    Duncan Murdoch
>>    On 2025-11-27 9:19 a.m., Marcelo Ventura Freire via R-devel wrote:
>>     > Hello, dear R core developers
>>     >
>>     >
>>     > I have a feature suggestion and, following the orientations in
>>     > https://contributor.r-project.org/rdevguide/chapters/
>>    submitting_feature_requests.html <https://contributor.r-project.org/
>>    rdevguide/chapters/submitting_feature_requests.html>,
>>     > I have searched in Bugzilla to the best of my capabilities for
>>    suggestions
>>     > like the one I have in mind but found no results (however, I can
>>    be wrong).
>>     >
>>     > My idea is including this line
>>     >
>>     > `%!in%`  <- function(x, table) match(x, table, nomatch = 0L) == 0L
>>     >
>>     > between lines 39 and 40 of the file "src/library/base/R/match.R".
>>     >
>>     > My objective is to create a "not in" operator that would allow us
>>    to write
>>     > code like
>>     >>     value %!in% valuelist
>>     > instead of
>>     >>     ! value %in% valuelist
>>     > which is in line with writing
>>     >>     value1 != value2
>>     > instead of
>>     >>     ! value1 == value2
>>     >
>>     > I was not able to devise any reasonable way that such inclusion
>>    would break
>>     > any already existing heritage code unless that operator would be
>>    defined
>>     > otherwisely and it would improve (however marginally) the
>>    readability of
>>     > future code by its intuitive interpretation and by stitching
>>    together two
>>     > operators that currently stand apart each other.
>>     >
>>     > So, if this suggestion was not already proposed and if it is seen as
>>     > useful, I would like to include it in the wishlist in Bugzilla.
>>     >
>>     > I would appreciate any feedback, be it critic or support, and I
>>    hope I have
>>     > not crossed any communicational rule from the group.
>>     >
>>     > Many thanks!  😄
>>     >
>>     >
>>     >
>>     > Marcelo Ventura Freire
>>     > Escola de Artes, Ciências e Humanidades
>>     > Universidade de São Paulo
>>     > Av. Arlindo Bettio, 1000,
>>     > Sala Paulo Freire (Sala Coletiva 252), Prédio I1
>>     > Ermelino Matarazzo, São Paulo, SP, Brasil
>>     > CEP 03828-000
>>     > Tel.: (11) 3091-8894
>>     >
>>     >       [[alternative HTML version deleted]]
>>     >
>>     > ______________________________________________
>>     > [email protected] <mailto:[email protected]> mailing list
>>     > https://stat.ethz.ch/mailman/listinfo/r-devel <https://
>>    stat.ethz.ch/mailman/listinfo/r-devel>
>> 
> 
> ______________________________________________
> [email protected] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 

______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to