Método sugerido para extrair uma biblioteca C autônoma de um pacote R existente?

8

Meu grupo está desenvolvendo um pacote R para simular o crescimento das plantas (consulte o repositório do GitHub ). O pacote R usa .Callpara fazer interface com C.

Decidimos que valeria a pena criar uma biblioteca C autônoma. Os dois principais motivos são: 1) usar ferramentas familiares de depuração C e 2) uma grande parte da comunidade de desenvolvedores / usuários está familiarizada com as linguagens compiladas (a maioria dos modelos da classe são escritos em C ou Fortran). No entanto, o pacote R é acessível a muitos fora desta comunidade, portanto, queremos manter sua funcionalidade.

Analisei algumas questões relacionadas, por exemplo, https://stackoverflow.com/q/12328156/199217 , que discutem pacotes R com dependências da biblioteca C, mas não encontrei uma que lida especificamente com a dissociação de um pacote R existente.

Uma abordagem proposta

(o que inventamos até agora ... um palhaço)

  1. Escreva testes para a funcionalidade existente
  2. mantenha a biblioteca C dentro da src/pasta
  3. Coloque o código C específico de R (por exemplo SEXP, carregando bibliotecas R, etc.) nos arquivos 'R wrapper' anexados comR_*
  4. crie funções separadas para ler arquivos de configuração em C
  5. crie uma função C 'principal' para substituir a funcionalidade em R
  6. escreva um makefile para a biblioteca C que ignora os arquivos do wrapper R
  7. Uma vez que a biblioteca C funcione de forma independente e equivalente ao pacote R, podemos considerar mover as funções C para um repositório separado, que seria uma dependência do pacote R

Questões:

  1. Esse esforço está equivocado?
  2. Estamos negligenciando possíveis armadilhas?
  3. Existe uma maneira melhor de desenvolver as bibliotecas R e C em paralelo?
  4. Existem exemplos de bibliotecas C que foram dissociadas dos pacotes R?
  5. Como podemos escrever testes para comparar funções equivalentes em R e C?
David LeBauer
fonte
Eu não sei internos R, mas em geral sobre a incorporação de uma biblioteca em algum intérprete você deve se preocupar muito sobre gerenciamento de memória (ou seja, coleta de lixo)
Basile Starynkevitch

Respostas:

2

De um modo geral, essa é uma boa idéia e muitos pacotes fazem isso. Você pode procurar RSQLiteinspiração - eles são empacotados sqlitee incluem apenas algumas funções de invólucro. Semelhante para rhdf5ehdf5

Em relação aos seus pontos:

Escreva testes para a funcionalidade existente

Sempre uma boa ideia!

Mantenha a biblioteca C dentro da src/pasta

Sim - ou você pode considerar inst/includese alguma vez seguiu a rota 'somente cabeçalho', a laRcpp

Coloque o código C específico de R (por exemplo SEXP, carregando bibliotecas R, etc.) nos arquivos 'R wrapper' anexados comR_*

Parece bastante sensato.

Crie funções separadas para ler arquivos de configuração em C

Não sei exatamente o que você quer dizer aqui.

Crie uma função C 'principal' para substituir a funcionalidade em R

Isso parece estranho para mim. Por que você precisa de um main- você não está apenas desenvolvendo uma biblioteca de funções que podem ser chamadas? Deixe R ser seu main:)

Escreva um makefile para a biblioteca C que ignora os arquivos do wrapper R

Sim, você provavelmente precisará de um envolvimento maior Makefilepara lidar com isso - sugiro novamente examinar o código-fonte do RSQLite, e também os R-exts podem ser úteis.

Uma vez que a biblioteca C funcione de forma independente e equivalente ao pacote R, podemos considerar mover as funções C para um repositório separado, que seria uma dependência do pacote R

Sim, isso parece sensato - peça ao pacote R que recupere o código-fonte C conforme necessário ao criar / desenvolver o pacote. Dessa forma, eles podem ser efetivamente dissociados.

Kevin Ushey
fonte
Obrigado. 1) "funções separadas para ler arquivos de configuração em C" é uma alternativa à nossa abordagem atual que usa xmlToList em R para ler um arquivo de entrada; 2) re "main" queremos poder calcular inteiramente em C passando uma configuração arquivo para o executável.
David LeBauer