Currently import
statements cannot be wrapped inside when
statements. Is there a workaround to this? I don’t want to stop using -vet-unused-imports
directive for the compiler.
I know about build tags and file suffixes, but is there a way they can be used with #config
constants set with -define
args?
If your concern is only errors from unused imports, you can declare them to _
to avoid that.
import "core:fmt"
_ :: fmt
// no error with -vet-unused-imports if fmt is never used
Otherwise, you can’t make the import itself conditional aside from build tags/file suffixes, which aren’t flexible for anything more than per-platform code selection. Generally, if you don’t use the contents of the package, it won’t end up in the final binary, so the import itself doesn’t actually need to be conditional.
This isn’t just “currently” but import
statements will never be allowed within when
statements. This is a lot more complicated than you might imagine and thus why it has been prevented.
Most of the time your imports should just be for that file only, and if you need platform specific code, use things like foo_windows.odin
or bar_amd64.odin
, or to use #+build
tags.
As for -vet-unused-imports
, there are three possible options to do:
_ :: fmt
@require import "core:fmt"
- this is not just to shut up
-vet
but to make it clear that you want the @(init)
/@(fini)
procedures for that package
#+vet !unused-imports
1 Like
If you want to use a conditional import, #+build
tags and magic suffixes are your only option, as gingerBill pointed out in the post above. This will work for platform-specific functionality, and if you wanted to use custom constants, you can wrap the contents of the imported file in a giant when statement.
So if I use the _ :: fmt
thing and don’t use the package, it’ll ignore the @(init)
functions of that package?
PS - what is @(fini)
, I couldn’t find it in docs.
The entry point procedure of Odin looks like the following:
- Initialize everything and call all
@(init)
procedures
- Call
main()
- Definitialize everything and call all
@(fini)
procedures.
@(fini)
is the opposite of @(init)
, it’s for executing code after main()
has finished executing.
Does the _ :: fmt
thing skip these calls if the pkg is not used?
In case anyone opens it looking for a different kind of workaround, I more or less hacked it in by using -collection:
compiler option.
For different kind of builds, I pass in two different implementation folders. It’s a bit iffy with language server but so would be the conditional imports. And it works. ![:smiley: :smiley:](https://forum.odin-lang.org/images/emoji/twitter/smiley.png?v=12)
No. Those calls are still called because it cannot know if you wanted to use it or not.
The difference between @(require)
and _ :: fmt
is purely aesthetic. @(require)
exists for foreign import
too, which makes it more consistent behaviour between import
and foreign import
.
1 Like
As someone who has to deal with python ecosystem I can add that conditional imports are pure evil. The behavior of the software magically changes when some condition you have never suspected to exist holds true. There is no good way to statically analyze such code and packaging becomes a nightmare.