[Bioc-devel] R6 class v.s. S4 class

Ryan Thompson rct at thompsonclan.org
Fri Oct 20 02:50:48 CEST 2017

Hi Chunlei,

One thing you could do to make the interface more traditional is to have a
global "query" function that takes a client object as an additional

Usage would be something like:

gene_client <- BioThingsClient("gene")
query("CDK2", client=gene_client)

To simplify this for common use cases, you could also have query accept
another argument named "type", which is just a string that is passed to
BioThingsClient to construct a new client on the spot:

query("CDK2", type="gene")

And thus the user never needs to interact directly with the client class
unless they need to set some other options besides the query type.
Obviously it should thrown an error if both client and type are passed.
Additionally, for interactive use, it might be useful to define an option
to set the default client to use if none is passed, e.g.

options(default.biothings.client = BioThingsClient("gene"))

Lastly, if you go this route, you will probably want to pick a more
specific name for the query function, this design makes it globally visible
rather attached to an object. More generally, all the function/argument
names I've provided are just example names.

Anyway, I'm not very experienced designing object-oriented interfaces in R,
but that's my 2 cents from a user perspective of how I would expect such an
R package to work. Hopefully others with more class design experience can
provide additional advice.


On Thu, Oct 19, 2017 at 5:25 PM Chunlei Wu <cwu at scripps.edu> wrote:

> Hello BioC-dev group,
>            We are working on a new R package right now and plan to submit
> it to Bioconductor soon.  It's a unified R client for the collection of
> BioThings APIs (http://biothings.io). Using R6 class, it makes a lot
> sense to me as I'm coming from Python's OOP experience. It will be used
> like this:
> library(biothings)
> gene_client <- BioThingsR6$new("gene")
> gene_client$query("CDK2")
> variant_client <- BioThingsR6$new("variant")
> gene_client$query("dbsnp.rsid:rs1000")
> Each "client" above is corresponding to a specific BioThings API, e.g. one
> for gene, and one for variant. And we will have more "clients" as we are
> expanding the number of BioThings API. The same R code should work with the
> future APIs.
> But if we use the traditional S4 class, it will be awkward as all
> functions/methods are not "namespaced", we will need to define new
> functions for each additional API. Something like this:
> library(biothings)
> geneQuery("CDK2")
> variantQuery("dbsnp.rsid:rs1000")
> I also want to mention that "query" is not the only method for each API
> client, there will be several other methods for each client. It will
> quickly make the function names messy if we go with the S4 option.
> Anyway, we think we like R6 class better, but just want to get some
> feedback here if the usage pattern using R6 class has been well-accepted in
> the R community. Will the users feel cumbersome if they have to instantiate
> the class first and then make the function calls? The majority of the
> existing BioC package are indeed S4 class based, which makes us feel
> hesitated.
> Thanks,
> Chunlei
>         [[alternative HTML version deleted]]
> _______________________________________________
> Bioc-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/bioc-devel

	[[alternative HTML version deleted]]

More information about the Bioc-devel mailing list