This is a scientific simulation C++ OOP modular project with user-contributed compilable plugins (but everything is compiled at the same time, so no runtime loading). What that means is any module may include definitions from any other module to work with that module. We specifically allow tight-coupling between modules should a module designer want to use this. This tight-coupling is quite the problem, otherwise we could enforce abstraction through composition or concepts, so maybe our situation is unique in this respect leading to the awkward solution below (3.C)
The naive approach to replace our project is to mirror the C++ use of forward declarations for type and function information allowing every module to have access to other module's information. But, Nim does not completely allow forward declarations.
Blindly forging ahead with import means we run into the cyclic imports problem.
I often see this as a solution to the 2 previous naive methods: basically put all your code in 1 file.
A) We could write the entire project in a single (gigantic) file and use the experimental codeReordering. Works! But eww. Asking module developers to "Cut and paste" their code is awful, and losing organization by file is awful, not to mention we lose module-level build caching and must rebuild the entire code all the time.
B) We can fix the organization problem by using a system of include statements to construct an all-in-one file at compile time. However, this does not play nicely with nimsuggest* and the developer experience is worse for it, requiring all developers to be expert and have memorized the code base. (* because nimsuggest is a static analysis tool so ignores include statements)
C) We can fix the nimsuggest problem by allowing faux modules, where users write a nim file as if they're writing a standard module and import all the other plugins or portions of the codebase as needed. However, as pointed out in approach 2, this will create cyclic imports. To fix this, we use a nimscript build file that preprocesses every file's import statements, stripping it of problematic imports, then constructing an all-in-one build file. Thus we get the appearance of forward declarations, the optimization of 1 define across all binary objects, and nimsuggest works! But wow, is this hoop-jumping really the "Nim way" for large projects of this nature?... Oh, and we have to rebuild the entire code base every time anything is changes :( .
We could force module developers to create entirely independent libraries (let's say static libraries) and if they require other types and functions from other plugins or portions of the codebase, then they have to include that possibly redundant code into their plugin. This would work, but may cause binary bloat - and I'm not even sure the vtables would work out linking the final executable with the multiple definitions.
All-In-One build, but must recompile the entire codebase for every change. Or Indipendent Libraries where each module is standalone and must include all code it needs to work, possibly bloating the final executable.
I'm so curious to hear your thoughts!
Hello, I liked your article. I have a project that is more than 5000 lines long, not counting the import modules, I also like you to test the include, but we lose information, so when hot, no problem but it is not viable, I have a very large screen but the cut in half is not enough, more often the editors have small beug, between the VS-Code mastodons which end up pedaling and the very light ones whose references are absent like Geany, I'm all alone so I'm doing well but if another person like in a company had to be on the same project ... I remember we had 3 big screens .... in short, that doesn't solve the very big ones projects we can also force to work and remodel in import moreover a question torments me we are not talking about exporting does import also export ??? So the / proc functions but as the "import" are objects then the data redefinitions ... well I discuss like that I think aloud. But I understood correctly and this applies to all Projects requiring code lines. On the AS400 we could do everything modular but everything communicated and there was one like shm.h and ipc.h of UDS and SDS and DS data-structures with pointer which made it possible to make the programming relational even the file declarations could be shared in "open data space". Well, I'm not asking for time, for example we had halved the purchase request and purchase validation program with independent files. There is also a lack of documentation (example related to definitions) for example as soon as you go down in the system see IPC SHM when you want an application to communicate with external programs to name a few ... In short in all this I find that NIM by itself is Reliable, certainly that they would need more people but that is another story. Maybe remember that Open-source does not want without donation;)
I use google for the translation excuse me
Apparently, Araq has pointed out that nimsuggest actually does track includes properly, but editors do not often make use of this feature. Bummer. But this would enable the 3.B solution, reducing the hoop-jumping by one layer :)
AFAIK only nim.nvim and nimlsp uses nimsuggest correctly :P I've verified this fact with the compiler source.
2) Nim does not allow cyclic imports
This is going to be the next priority after IC lands in Nim, so it should be out ~1.6 (next major release).
Can anyone shed light on how to properly configure VSCode? I already tried it a couple days ago, and autocomplete with nimsuggest fails to process the includes.
{
// settings.json
"nim.project": [
"main.nim"
]
}
AFAIK only nim.nvim and nimlsp uses nimsuggest correctly :P I've verified this fact with the compiler source.
what exactly do you mean by that? There isn't much which can be done wrong, except for the one nimsuggest process/per file relict vscode-nim has which doesn't happen if a project file is specified (admittedly finding the project file can be done mostly automatically). Nimlsp has it's own problems. Last I time I tried it, the most severe one being that all analysis seems to be limited to things imported from outside the current project.
There isn't much which can be done wrong, except for the one nimsuggest process/per file relict vscode-nim has which doesn't happen if a project file is specified (admittedly finding the project file can be done mostly automatically).
Yep that's the issue. VSCode can't do it automatically. nim.nvim and (maybe?) nimlsp can perform analysis to select the correct file no matter which file you open, which makes things much simpler.
2) Nim does not allow cyclic imports
This is going to be the next priority after IC lands in Nim, so it should be out ~1.6 (next major release).
This would be fantastic. Is this officially planned? I haven't seen any reference to it anywhere else.