I use this post to tell about a problem I currently have, and a limitation of 
imports/include/export system and preserving public/private API. In the 
nim-lang/bigints library, I tried to refactor the library that is currently a 
file with 1200 lines.

All the functions/procedures/templates depend on the Bigint type, whose type is 
exported but not the fields.

I cannot directly access the type from other files without exporting the 
fields, but in our API, the fields must stay private.

So I have fallen back to includes. In our nimble directory layout, we have a 
src directory with bigints.nim (main file of the library) and a directory 
bigints.

  * src/
    * bigints.nim
    * bigints
      * some other files



So I have tried to split bigints.nim into multiple files put under bigints 
directory and include them in bigints.nim. (Here, I had the same need to 
include a whole directory in a file).

The problem is, if I include all them separately, I can not compile each file 
separately (due to dependencies between each other files), making maintenance 
and editing complex (my editor sees error everywhere, because each file is not 
compilable).

So I have tried to make a "linked chain" of includes : each small file includes 
the previous (in the order that they were extracted from the huge monolithic 
current file bigints.nim), and the last small file is included in the main file 
bigints.nim.

This solves almost all problems, except forward declaration, for procedures 
using procedures in next files, the forward declaration can not be in a file 
different than the procedure declared. We are thus forced to regroup the 
procedures in a same huge file.

Concerning forward declaration, I wish we had a system similar to prototypes in 
C and header files. It looks cumbersome to any beginning programmer, but it 
looks like the more stable system in the end.

One way to avoid the includes, would be to do another smaller main file 
bigints2.nim in the bigints subdirectory, make every field public, import 
everything in bigints2.nim and then import bigints2.nim in the library file 
bigints.nim. I am not sure this double import hides the public fields though :(

Currently I have no satisfying solution on how to have both a library with 
splitted files and keep internals private to the end user. 

Reply via email to