R C api for 'inherits' S3 and S4 objects

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

R C api for 'inherits' S3 and S4 objects

Jan Gorecki
Dear R developers,

Motivated by discussion about checking inheritance of S3 and S4
objects (in head matrix/array topic) I would light to shed some light
on a minor gap about that matter in R C API.
Currently we are able to check inheritance for S3 class objects from C
in a robust way (no allocation, thread safe). This is unfortunately
not possible for S4 classes. I would kindly request new function in R
C api so it can be achieved for S4 classes with no risk of allocation.
For reference mentioned functions below. Thank you.
Jan Gorecki

// S3 inheritance
bool INHERITS(SEXP x, SEXP char_) {
  SEXP klass;
  if (isString(klass = getAttrib(x, R_ClassSymbol))) {
    for (int i=0; i<LENGTH(klass); i++) {
      if (STRING_ELT(klass, i) == char_) return true;
    }
  }
  return false;
}
// S4 inheritance
bool Rinherits(SEXP x, SEXP char_) {
  SEXP vec = PROTECT(ScalarString(char_));
  SEXP call = PROTECT(lang3(sym_inherits, x, vec));
  bool ans = LOGICAL(eval(call, R_GlobalEnv))[0]==1;
  UNPROTECT(2);
  return ans;
}

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [External] R C api for 'inherits' S3 and S4 objects

Tierney, Luke
On Fri, 1 Nov 2019, Jan Gorecki wrote:

> Dear R developers,
>
> Motivated by discussion about checking inheritance of S3 and S4
> objects (in head matrix/array topic) I would light to shed some light
> on a minor gap about that matter in R C API.
> Currently we are able to check inheritance for S3 class objects from C
> in a robust way (no allocation, thread safe). This is unfortunately

Your premise is not correct. Rf_inherits will not GC but it can
allocate and is not thread safe.

Best,

luke

> not possible for S4 classes. I would kindly request new function in R
> C api so it can be achieved for S4 classes with no risk of allocation.
> For reference mentioned functions below. Thank you.
> Jan Gorecki
>
> // S3 inheritance
> bool INHERITS(SEXP x, SEXP char_) {
>  SEXP klass;
>  if (isString(klass = getAttrib(x, R_ClassSymbol))) {
>    for (int i=0; i<LENGTH(klass); i++) {
>      if (STRING_ELT(klass, i) == char_) return true;
>    }
>  }
>  return false;
> }
> // S4 inheritance
> bool Rinherits(SEXP x, SEXP char_) {
>  SEXP vec = PROTECT(ScalarString(char_));
>  SEXP call = PROTECT(lang3(sym_inherits, x, vec));
>  bool ans = LOGICAL(eval(call, R_GlobalEnv))[0]==1;
>  UNPROTECT(2);
>  return ans;
> }
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

--
Luke Tierney
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:   [hidden email]
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [External] R C api for 'inherits' S3 and S4 objects

Jan Gorecki
Thank you Luke.
That is why I don't use Rf_inherits but INHERITS which does not
allocate, provided in the email body.
I cannot do similarly for S4 classes, thus asking for some API for that.

On Fri, Nov 1, 2019 at 5:56 PM Tierney, Luke <[hidden email]> wrote:

>
> On Fri, 1 Nov 2019, Jan Gorecki wrote:
>
> > Dear R developers,
> >
> > Motivated by discussion about checking inheritance of S3 and S4
> > objects (in head matrix/array topic) I would light to shed some light
> > on a minor gap about that matter in R C API.
> > Currently we are able to check inheritance for S3 class objects from C
> > in a robust way (no allocation, thread safe). This is unfortunately
>
> Your premise is not correct. Rf_inherits will not GC but it can
> allocate and is not thread safe.
>
> Best,
>
> luke
>
> > not possible for S4 classes. I would kindly request new function in R
> > C api so it can be achieved for S4 classes with no risk of allocation.
> > For reference mentioned functions below. Thank you.
> > Jan Gorecki
> >
> > // S3 inheritance
> > bool INHERITS(SEXP x, SEXP char_) {
> >  SEXP klass;
> >  if (isString(klass = getAttrib(x, R_ClassSymbol))) {
> >    for (int i=0; i<LENGTH(klass); i++) {
> >      if (STRING_ELT(klass, i) == char_) return true;
> >    }
> >  }
> >  return false;
> > }
> > // S4 inheritance
> > bool Rinherits(SEXP x, SEXP char_) {
> >  SEXP vec = PROTECT(ScalarString(char_));
> >  SEXP call = PROTECT(lang3(sym_inherits, x, vec));
> >  bool ans = LOGICAL(eval(call, R_GlobalEnv))[0]==1;
> >  UNPROTECT(2);
> >  return ans;
> > }
> >
> > ______________________________________________
> > [hidden email] mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
> >
>
> --
> Luke Tierney
> Ralph E. Wareham Professor of Mathematical Sciences
> University of Iowa                  Phone:             319-335-3386
> Department of Statistics and        Fax:               319-335-3017
>     Actuarial Science
> 241 Schaeffer Hall                  email:   [hidden email]
> Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [External] R C api for 'inherits' S3 and S4 objects

Gábor Csárdi
AFAIR getAttrib() can allocate as well. Also, R API functions that do
not allocate today, may allocate in the future.

Gabor

On Fri, Nov 1, 2019 at 1:24 PM Jan Gorecki <[hidden email]> wrote:

>
> Thank you Luke.
> That is why I don't use Rf_inherits but INHERITS which does not
> allocate, provided in the email body.
> I cannot do similarly for S4 classes, thus asking for some API for that.
>
> On Fri, Nov 1, 2019 at 5:56 PM Tierney, Luke <[hidden email]> wrote:
> >
> > On Fri, 1 Nov 2019, Jan Gorecki wrote:
> >
> > > Dear R developers,
> > >
> > > Motivated by discussion about checking inheritance of S3 and S4
> > > objects (in head matrix/array topic) I would light to shed some light
> > > on a minor gap about that matter in R C API.
> > > Currently we are able to check inheritance for S3 class objects from C
> > > in a robust way (no allocation, thread safe). This is unfortunately
> >
> > Your premise is not correct. Rf_inherits will not GC but it can
> > allocate and is not thread safe.
> >
> > Best,
> >
> > luke
> >
> > > not possible for S4 classes. I would kindly request new function in R
> > > C api so it can be achieved for S4 classes with no risk of allocation.
> > > For reference mentioned functions below. Thank you.
> > > Jan Gorecki
> > >
> > > // S3 inheritance
> > > bool INHERITS(SEXP x, SEXP char_) {
> > >  SEXP klass;
> > >  if (isString(klass = getAttrib(x, R_ClassSymbol))) {
> > >    for (int i=0; i<LENGTH(klass); i++) {
> > >      if (STRING_ELT(klass, i) == char_) return true;
> > >    }
> > >  }
> > >  return false;
> > > }
> > > // S4 inheritance
> > > bool Rinherits(SEXP x, SEXP char_) {
> > >  SEXP vec = PROTECT(ScalarString(char_));
> > >  SEXP call = PROTECT(lang3(sym_inherits, x, vec));
> > >  bool ans = LOGICAL(eval(call, R_GlobalEnv))[0]==1;
> > >  UNPROTECT(2);
> > >  return ans;
> > > }
> > >
> > > ______________________________________________
> > > [hidden email] mailing list
> > > https://stat.ethz.ch/mailman/listinfo/r-devel
> > >
> >
> > --
> > Luke Tierney
> > Ralph E. Wareham Professor of Mathematical Sciences
> > University of Iowa                  Phone:             319-335-3386
> > Department of Statistics and        Fax:               319-335-3017
> >     Actuarial Science
> > 241 Schaeffer Hall                  email:   [hidden email]
> > Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [External] R C api for 'inherits' S3 and S4 objects

Simon Urbanek
In reply to this post by Jan Gorecki
Note that your desire is by definition impossible - as your example also shows checking for S4 inheritance involves evaluation and thus allocation which cannot be avoided by the dynamic design of S4 inheritance.

Cheers,
Simon


> On Nov 1, 2019, at 9:23 AM, Jan Gorecki <[hidden email]> wrote:
>
> Thank you Luke.
> That is why I don't use Rf_inherits but INHERITS which does not
> allocate, provided in the email body.
> I cannot do similarly for S4 classes, thus asking for some API for that.
>
> On Fri, Nov 1, 2019 at 5:56 PM Tierney, Luke <[hidden email]> wrote:
>>
>> On Fri, 1 Nov 2019, Jan Gorecki wrote:
>>
>>> Dear R developers,
>>>
>>> Motivated by discussion about checking inheritance of S3 and S4
>>> objects (in head matrix/array topic) I would light to shed some light
>>> on a minor gap about that matter in R C API.
>>> Currently we are able to check inheritance for S3 class objects from C
>>> in a robust way (no allocation, thread safe). This is unfortunately
>>
>> Your premise is not correct. Rf_inherits will not GC but it can
>> allocate and is not thread safe.
>>
>> Best,
>>
>> luke
>>
>>> not possible for S4 classes. I would kindly request new function in R
>>> C api so it can be achieved for S4 classes with no risk of allocation.
>>> For reference mentioned functions below. Thank you.
>>> Jan Gorecki
>>>
>>> // S3 inheritance
>>> bool INHERITS(SEXP x, SEXP char_) {
>>> SEXP klass;
>>> if (isString(klass = getAttrib(x, R_ClassSymbol))) {
>>>   for (int i=0; i<LENGTH(klass); i++) {
>>>     if (STRING_ELT(klass, i) == char_) return true;
>>>   }
>>> }
>>> return false;
>>> }
>>> // S4 inheritance
>>> bool Rinherits(SEXP x, SEXP char_) {
>>> SEXP vec = PROTECT(ScalarString(char_));
>>> SEXP call = PROTECT(lang3(sym_inherits, x, vec));
>>> bool ans = LOGICAL(eval(call, R_GlobalEnv))[0]==1;
>>> UNPROTECT(2);
>>> return ans;
>>> }
>>>
>>> ______________________________________________
>>> [hidden email] mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>
>> --
>> Luke Tierney
>> Ralph E. Wareham Professor of Mathematical Sciences
>> University of Iowa                  Phone:             319-335-3386
>> Department of Statistics and        Fax:               319-335-3017
>>    Actuarial Science
>> 241 Schaeffer Hall                  email:   [hidden email]
>> Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [External] R C api for 'inherits' S3 and S4 objects

Tierney, Luke
In reply to this post by Jan Gorecki
On Fri, 1 Nov 2019, Jan Gorecki wrote:

> Thank you Luke.
> That is why I don't use Rf_inherits but INHERITS which does not
> allocate, provided in the email body.

Your definition can allocate because STING_ELT can allocate.
getAttrib can GC in general. Currently it would not GC or allocate in
this case, but this could change.

You can't assume thread-safety for calls into the R API, or any API
for that matter, unless they are documented to be thread-safe.

You would be better off using Rf_inherits as it does not make the
assumption that you can use pointer comparisons to check for identical
strings.  CHARSXPs are almost always cached but they are not
guaranteed to be, and the caching strategy might change in the future.

Best,

luke

> I cannot do similarly for S4 classes, thus asking for some API for that.
>
> On Fri, Nov 1, 2019 at 5:56 PM Tierney, Luke <[hidden email]> wrote:
>>
>> On Fri, 1 Nov 2019, Jan Gorecki wrote:
>>
>>> Dear R developers,
>>>
>>> Motivated by discussion about checking inheritance of S3 and S4
>>> objects (in head matrix/array topic) I would light to shed some light
>>> on a minor gap about that matter in R C API.
>>> Currently we are able to check inheritance for S3 class objects from C
>>> in a robust way (no allocation, thread safe). This is unfortunately
>>
>> Your premise is not correct. Rf_inherits will not GC but it can
>> allocate and is not thread safe.
>>
>> Best,
>>
>> luke
>>
>>> not possible for S4 classes. I would kindly request new function in R
>>> C api so it can be achieved for S4 classes with no risk of allocation.
>>> For reference mentioned functions below. Thank you.
>>> Jan Gorecki
>>>
>>> // S3 inheritance
>>> bool INHERITS(SEXP x, SEXP char_) {
>>>  SEXP klass;
>>>  if (isString(klass = getAttrib(x, R_ClassSymbol))) {
>>>    for (int i=0; i<LENGTH(klass); i++) {
>>>      if (STRING_ELT(klass, i) == char_) return true;
>>>    }
>>>  }
>>>  return false;
>>> }
>>> // S4 inheritance
>>> bool Rinherits(SEXP x, SEXP char_) {
>>>  SEXP vec = PROTECT(ScalarString(char_));
>>>  SEXP call = PROTECT(lang3(sym_inherits, x, vec));
>>>  bool ans = LOGICAL(eval(call, R_GlobalEnv))[0]==1;
>>>  UNPROTECT(2);
>>>  return ans;
>>> }
>>>
>>> ______________________________________________
>>> [hidden email] mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>
>> --
>> Luke Tierney
>> Ralph E. Wareham Professor of Mathematical Sciences
>> University of Iowa                  Phone:             319-335-3386
>> Department of Statistics and        Fax:               319-335-3017
>>     Actuarial Science
>> 241 Schaeffer Hall                  email:   [hidden email]
>> Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu
>

--
Luke Tierney
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:   [hidden email]
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: R C api for 'inherits' S3 and S4 objects

R devel mailing list
In reply to this post by Jan Gorecki
If your goal is to perform multithreaded computations, why not perform
all necessary interactions with R upfront and then compute only on
primitives? It would help for us to understand your use case.

On Fri, Nov 1, 2019 at 4:26 AM Jan Gorecki <[hidden email]> wrote:

>
> Dear R developers,
>
> Motivated by discussion about checking inheritance of S3 and S4
> objects (in head matrix/array topic) I would light to shed some light
> on a minor gap about that matter in R C API.
> Currently we are able to check inheritance for S3 class objects from C
> in a robust way (no allocation, thread safe). This is unfortunately
> not possible for S4 classes. I would kindly request new function in R
> C api so it can be achieved for S4 classes with no risk of allocation.
> For reference mentioned functions below. Thank you.
> Jan Gorecki
>
> // S3 inheritance
> bool INHERITS(SEXP x, SEXP char_) {
>   SEXP klass;
>   if (isString(klass = getAttrib(x, R_ClassSymbol))) {
>     for (int i=0; i<LENGTH(klass); i++) {
>       if (STRING_ELT(klass, i) == char_) return true;
>     }
>   }
>   return false;
> }
> // S4 inheritance
> bool Rinherits(SEXP x, SEXP char_) {
>   SEXP vec = PROTECT(ScalarString(char_));
>   SEXP call = PROTECT(lang3(sym_inherits, x, vec));
>   bool ans = LOGICAL(eval(call, R_GlobalEnv))[0]==1;
>   UNPROTECT(2);
>   return ans;
> }
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



--
Michael Lawrence
Senior Scientist, Bioinformatics and Computational Biology
Genentech, A Member of the Roche Group
Office +1 (650) 225-7760
[hidden email]

Join Genentech on LinkedIn | Twitter | Facebook | Instagram | YouTube

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: [External] R C api for 'inherits' S3 and S4 objects

Jan Gorecki
In reply to this post by Tierney, Luke
Thank you all for your valuable comments.
Best,
Jan

On Fri, Nov 1, 2019 at 8:15 PM Tierney, Luke <[hidden email]> wrote:

>
> On Fri, 1 Nov 2019, Jan Gorecki wrote:
>
> > Thank you Luke.
> > That is why I don't use Rf_inherits but INHERITS which does not
> > allocate, provided in the email body.
>
> Your definition can allocate because STING_ELT can allocate.
> getAttrib can GC in general. Currently it would not GC or allocate in
> this case, but this could change.
>
> You can't assume thread-safety for calls into the R API, or any API
> for that matter, unless they are documented to be thread-safe.
>
> You would be better off using Rf_inherits as it does not make the
> assumption that you can use pointer comparisons to check for identical
> strings.  CHARSXPs are almost always cached but they are not
> guaranteed to be, and the caching strategy might change in the future.
>
> Best,
>
> luke
>
> > I cannot do similarly for S4 classes, thus asking for some API for that.
> >
> > On Fri, Nov 1, 2019 at 5:56 PM Tierney, Luke <[hidden email]> wrote:
> >>
> >> On Fri, 1 Nov 2019, Jan Gorecki wrote:
> >>
> >>> Dear R developers,
> >>>
> >>> Motivated by discussion about checking inheritance of S3 and S4
> >>> objects (in head matrix/array topic) I would light to shed some light
> >>> on a minor gap about that matter in R C API.
> >>> Currently we are able to check inheritance for S3 class objects from C
> >>> in a robust way (no allocation, thread safe). This is unfortunately
> >>
> >> Your premise is not correct. Rf_inherits will not GC but it can
> >> allocate and is not thread safe.
> >>
> >> Best,
> >>
> >> luke
> >>
> >>> not possible for S4 classes. I would kindly request new function in R
> >>> C api so it can be achieved for S4 classes with no risk of allocation.
> >>> For reference mentioned functions below. Thank you.
> >>> Jan Gorecki
> >>>
> >>> // S3 inheritance
> >>> bool INHERITS(SEXP x, SEXP char_) {
> >>>  SEXP klass;
> >>>  if (isString(klass = getAttrib(x, R_ClassSymbol))) {
> >>>    for (int i=0; i<LENGTH(klass); i++) {
> >>>      if (STRING_ELT(klass, i) == char_) return true;
> >>>    }
> >>>  }
> >>>  return false;
> >>> }
> >>> // S4 inheritance
> >>> bool Rinherits(SEXP x, SEXP char_) {
> >>>  SEXP vec = PROTECT(ScalarString(char_));
> >>>  SEXP call = PROTECT(lang3(sym_inherits, x, vec));
> >>>  bool ans = LOGICAL(eval(call, R_GlobalEnv))[0]==1;
> >>>  UNPROTECT(2);
> >>>  return ans;
> >>> }
> >>>
> >>> ______________________________________________
> >>> [hidden email] mailing list
> >>> https://stat.ethz.ch/mailman/listinfo/r-devel
> >>>
> >>
> >> --
> >> Luke Tierney
> >> Ralph E. Wareham Professor of Mathematical Sciences
> >> University of Iowa                  Phone:             319-335-3386
> >> Department of Statistics and        Fax:               319-335-3017
> >>     Actuarial Science
> >> 241 Schaeffer Hall                  email:   [hidden email]
> >> Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu
> >
>
> --
> Luke Tierney
> Ralph E. Wareham Professor of Mathematical Sciences
> University of Iowa                  Phone:             319-335-3386
> Department of Statistics and        Fax:               319-335-3017
>     Actuarial Science
> 241 Schaeffer Hall                  email:   [hidden email]
> Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

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