I mean not by changing the system.nim manually but somehow as a part of this or that project.
Namely, I would like to have my own assert which does not throw exception but simply shows message and exits. This would allow to compile code like:
proc foo(i : int) {.no_side_effect.} =
assert(i > 0)
... # really no side effects
Yes, but I'm not sure this is "best practice". Simply make an overrides.nim file with a proc assert(...) in it, then put include=overrides in one of the many nimrod config files (or simply put --include:overrides in the command line) to implicitly include the overrides in every source file of your project. You can still access system.assert(...) but be careful of overriding symbols which may cause conflicts within your own modules, and you most likely don't want to expose any symbol from the overrides file or each module of your project will expose a duplicated symbol.
Perhaps a better practice would be to make a my.nim with your overrides in it and use import=my instead, which would require you to explicitly type my.assert(...) and system.assert(...) everywhere. Less confusing for others reading your code, and faster compile times too (not that I imagine including a basic file would really slow things down).
It looks that only templates can be redefined. Perhaps the ability to override could be extended to other parts of the language, not in "everyday's normal code", only when one uses this trick. Yes, it is ugly and dangerous and everything but it may be more convenient than touching a foreign code.
Possible use cases:
It looks that only templates can be redefined.
No, the include trick should work with pretty much everything but for overloaded symbols you have to ensure the signature matches the same or better than the signature that you seek to override.
Araq: I tried to "redefine" (meaning completely replace the ordinary code in a module with my own) types and procs and neither did work. Template did, even within single module without using the above mentioned "include trickery".
Apart of assert one may wish to intercept manual allocation calls (in 3pp libraries) and replace them with custom re-implementation. I do this for C code, my allocation routines do lot of checking and bookkeeping.