Hi! Suppose I have a module like this:
# foo.nim
const text = slurp("text.txt")
static:
echo text
Let's say I import it from another module, named bar.nim. Every time I compile bar.nim, the static block gets executed, even if nothing has changed in either module. It's a little odd that the compiler bothers to parse the unaltered foo.nim, but it looks like it doesn't actually compile anything, because it doesn't modify the corresponding .c and .o files in the cache. If I change only text.txt, though, the compiler catches this and updates the cache. How does it know that the contents of the text file have changed? Is there some special handling related to slurp which compares the modification date on the module to that of the text file? If I remove the echo line from the static block, will the compiler keep reading the text file anyway, or does that happen lazily? What if I have some macro that generates code based on the contents of text.txt and I call it in foo.nim? Will it be ignored as long as these files don't change?
[EDIT] Upon further experimentation, it looks like macros get invoked even when no files are modified. The cache doesn't get updated, so I guess the results of the macro invocation are simply discarded instead of being compiled? Is there any way to prevent this useless work from being done? Does this only happen for macros with side-effects? I tried testing this using a long computation in a macro, but the VM just bails out.
It's a little odd that the compiler bothers to parse the unaltered foo.nim, but it looks like it doesn't actually compile anything, because it doesn't modify the corresponding .c and .o >files in the cache.
Araq, I think he wants that Nim source files are only compiled when changed, maybe when creation date has changed.
Stas, I guess the Nim Compiler compiles Nim source text to temporary destination, maybe in Ram, and compares it to files in nimcache directory. And copies it only to mimcache directory when it is not identical. So C compiler can skip it when unchanged, as .o file is available. Just my personal guess.
@Araq: As far as I can tell, when a macro has side-effects (e.g. echo), its invocations get re-evaluated, even if the macro itself and the modules containing the invocations remain unchanged. Is the compiler smart enough to only do that with macros that have side-effects? What happens if the macro breaks referential transparency in a trickier way (e.g. it generates code based on the contents of a file)?
@Stefan_Salewski: I hope you're wrong, because that would defeat the purpose of having a cache in the first place.
I don't know how clever a compiler you want, but as far I understand, macro always evaluated during compile time.
If not, you get the macro what do you usually works with C, just a simple textual substitution. And that's not what you want, really.
@StasB, the macro wouldn't be evaluated if not used, evaluated if used. If not used, you won't get the transformed/generated code
@Udiknedorm, yes, some operations just cannot be evaluated during compile time, but macro in Nim still evaluating what it can for compile-time operations.