5 ms·
That is starkraving insanity, and now highlights why there is a whole submission about making a Zig IDE. So I guess if one wanted to do any refactoring, be sure
by mdaniel 4y ago
That is starkraving insanity, and now highlights why there is a whole submission about making a Zig IDE. So I guess if one wanted to do any refactoring, be sure to go through and uncomment every code flow in the app first
And look, I can appreciate lazy evaluation being awesome in some circumstance, but `fn wat() void { 1 + ""; }` just spits in the face of static typing
- dilap 4y agoA nice thing you get in return tho is for separate platforms you can disable code just in the language itself; it doesn't need to be a preprocessor or or handled magically in the build system. It's also not nearly as bad as a dynamically typed language: you might have broken code you won't realize until you try to use it, but you'll always realize at compile-time. In dynamic languages you refactor and don't notice you broke stuff until runtime!
- dleslie 4y agoUncommenting a line for a platform-specific feature isn't really any more difficult than decorating a function, adding a pre-processor gate, or any of the other normal ways of doing it.
- dilap 4y agomore difficult maybe maybe not, but the way zig does it is simpler in that it's fewer languages you have to know: you don't have to learn the c preprocessor (c/c++) or about magic +build tags (Go) or whatever; it's just normal conditionals in the same language. you might [reasonably] say you can't care about that kind of simplicity, which is fine; but radical simplicity is definitely one of the major charms of zig. (and you don't use the zig feature by commenting/uncommenting, it's via inspection of the environment/flags in the comptime code.)
- Kwpolska 4y agoSo how does Zig handle platform-specific stuff that cannot be compiled on other platforms? Is it an `if` resolved at compile time causing the uncompileable code to be unused and disappear after the Zir stage? You don't need a full preprocessor with macros and other evil stuff. Just #define and #ifdef would solve this without allowing wrong code that randomly disappears. And learning and understanding these two directives requires zero mental effort.
- TUSF 4y ago> Is it an `if` resolved at compile time causing the uncompileable code to be unused and disappear after the Zir stage? Yes. It's exactly that, because Zig very aggressively evaluates values that are known at compile time. It's as simple as: if (builtin.os.tag == .linux) { // Everything here only exists if compiling for Linux. } The standard library uses this quite a lot for OS/CPU specific things.
- dleslie 4y agoThat's elegant. It's also not so different than a preprocessor gate, or a function attribute.
- Kwpolska 4y agoI don’t agree that it’s elegant. A preprocessor directive or a function attribute makes it more obvious that the code it covers may be valid only in some conditions. On the other hand, if the language optimizes some `if` statements out, you may have invalid code without noticing — and not only in the case of OS-specific code, but possibly also regular code whose `if` condition became a compile-time constant, even unintentionally/temporarily/by mistake.
- wtetzner 4y agoI think it’s elegant, but it seems to me that the check shouldn’t be evaluated until after type checking. But I’m probably missing something about the way Zig works.
- dleslie 4y agoIf you're already concerned with, and developing, platform-specific code then the extra knowledge isn't really that hard to grasp. Moreover, I can grep for preprocessor defines, attributes, and such by name. There's no way to grep a project for code commented out to prevent execution on some platforms.
- dontlaugh 4y agoIt’s not necessarily simpler than an explicit hygienic macro system or similar, since comptime is a complex feature with surprising consequences. Mostly it moves the complexity around.
- throwawaymaths 4y agoI work in a language with hygienic macros and in zig, and zigs way is simpler and more constrained.
- notduncansmith 4y agoIt seems like a nice balance might be a compiler config that accepts a list of paths to unconditionally compile, so that users can enforce stricter checks in their own project without forcing authors of their dependencies to do the same.
- lostmsu 4y ago> compiler config How is this better than a line in the language itself?
- notduncansmith 4y agoEven better
- throwawaymaths 4y agoDoesn't @refalldecls do this?
- anonymoushn 4y agoThis does it, but you might still find compile errors later than you'd like in comptime-heavy code.
- throwawaymaths 4y agoIt's the carrot to get you to write tests. You're writing tests, right?
- jay-barronville 4y ago> A nice thing you get in return tho is for separate platforms you can disable code just in the language itself; it doesn't need to be a preprocessor or or handled magically in the build system. I don’t know if I consider this a nice thing when thinking about it from a systems language lens. When working at the low level, I like the immediate clarity and compile-time feedback that preprocessor-like checks bring. They’re not perfect, but I think I prefer that instead of relying on laziness. > It's also not nearly as bad as a dynamically typed language: you might have broken code you won't realize until you try to use it, but you'll always realize at compile-time. This is correct, but to me, the elephant in the room here though is that this makes it much easier to introduce broken technical debt into a codebase. This likely means that when conducting large-scale refactors in a Zig codebase, as the amount of potentially broken code increases, the count of hair strands remaining in one’s scalp decreases. Zig is an awesome language, but frankly, I think compiler laziness like this is pretty odd for a statically-typed systems language and not the behavior one would intuitively expect.
- flohofwoe 4y agoIt's pretty much a necessity for conditionally compiled platform-specific code if you don't have a text-based preprocessor with #ifdef/#endif. All statically compiled languages need to skip compiling such code one way or another. Zig is just thinking this idea to the end and doesn't compile any dead code. I guess the recommended workflow is to have good test coverage. The test basically turns dead code back into live code.
- layer8 4y agoThis is reminiscent of C++ templates that fail with inscrutable errors deep in their implementation (only) when instantiated for particular types. I’m sure there is a better way.
- throwawaymaths 4y agoIt's kind of not. One way to think of it is roughly as follows: Zig is statically typed at runtime. It's dynamically typed at compile time. Anyways it's not entirely crazy to think that maybe this sort of thing should be the province of static linters
- nyberg 4y agoOne would just run tests and rebuild for the supported targets? That will hit all comptime branches that you care about without needing to do anything else. I don't see how this is much worse? What you seem to be looking for is an "unused function" (https://github.com/ziglang/zig/issues/335 https://github.com/ziglang/zig/issues/335) error instead as it catches that case unless you use the function in a branch that's not part of your target set (truly dead unused code). There's support for invoking with qemu, wine, etc in the build system which allows you to run tests for other platforms. A case where I've taken advantage if this is to have data structures and code adjust based on the expected page size and cache-line. There are also cases where things may be both comptime and runtime known depending on which platform that you target which is easy to handle by having the maybe comptime value be first in conditional branches.