-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
remove lazy analysis from zig #2529
Comments
What are the issues in the code that you think should produce compile-time errors? |
Something like:
I'm not including the divide by zero on line 10. All of the others can I believe be gained by switching on comptime evaluation for dead code (outside of tests) I realize these errors don't reduce bugs in the binary. But they certainly reduce bugs in the code! Which can only be a good thing As I understand it, currently code can be either 1) maximally checked 2) checked when I propose that option number 3 be removed Assuming I've understood things correctly, imagine importing any external library into your code. Currently the guarantee is just (3) that identifiers are syntactically correct |
Lazy analysis is one of the core design premises of zig; it's going to be very difficult to change at this point. Lots of things rely on it. I recognize there is a problem that it can be difficult to refactor code that is not covered by tests. I do want to handle this use case better, and I have some ideas. I'll leave this open to track the existence of this use case / unsolved problem scenario, until it's decided to do something about it or not. |
Zig is extremely well designed in my opinion, and
So there are probably things I'm missing, but:
I wonder if compiler caching could be done not at the file level, but at the top declaration level -- with the cache keys being either the strings input into the parser, or a compacted output from the parser. This could be interesting to consider Apart from the first compilation, this is in one sense lazier than the current design, since only changed declarations would get recompiled, and yet it would also mean zig validates 1:1 what the programmer sees, rather than a subset I'm sure that has technical challenges though. I've thought of a potential way to solve link-time slow down. Other issues might be employing lazy analysis for evaluating infinite loops and other things. I don't know. But I wonder: Being simplistic, lazy analysis is really, I assume, a time/correctness tradeoff. Saving time, for the sake of correctness. What are the actual % savings by being lazy in Debug mode? I imagine the major cost is (for the first compile) in llvm code-gen for each import, which would NOT appreciate eager analysis Can we fix that by being lazy just for out-of-tree imports. Or share caches across projects, by placing caches relative to the imported files -- or have a common cache with the std library??? So, many ideas, but my least favorite of which is zig telling me code is correct, when it isn't... |
Sorry, one more comment: Lazy analysis is generally not an optimization Yes, for ReleaseFast/ReleaseSmall I can imagine people downloading green code, and simply compiling it once. In that case lazy analysis makes sense, and becomes some kind of comptime equivalent of undefined behavior But imagine a programmer in Debug mode using N functions from a library. They will add one function; compile/test; repeat. With eager analysis those functions will be parsed/compiled once. With lazy analysis I believe they will be parsed every time, and compiled factorial(N). Whatever the precise details, in this common case eager analysis is a massive saving..... -- even if the net saving is unclear, the programmer is paying more upfront, and so skips payments during the compile/test cycle. Also lazy analysis increases the risk of the Nth function not working To quote:
Sorry if I'm pressing the point too much, I think this is my last comment ;) |
I believe this is addressed by #3028. |
Hiya thanks for the #3028 proposal. This comment should maybe go there, but I don't want to presume, or stand in your way
Mmm. Yes only if every branch not taken has a target/test. So I think mostly No... For two reasons:
If I had started with the lockless call from the executable, I'd of just gained an executable that crashes or doesn't compile -- and also that's the easy step. So instead I first built up the functionality using C compiler errors to check and guide what I was doing While I see good points in your proposal, it would not have helped me implement that functionality
So while proposal #3028 reduces the amount of dead code left unchecked, it certainly does not remove all of it; and just by looking at the code, it can be very hard to know what code the compiler considers dead -- major bugs have entered software through optimization passes doing elision for instance I don't know if you will find those thoughts helpful or not. But assuming they contain some validity, what might I do about them?
I've got no experience of running multibuilds. So no real input to give here: Whether it makes the ui better, or if were just simpler to call the compiler once for each build? That's a separate question, but something that may retain a little of the multibuild concept, but also resolve issue #2595 (at least for me) would be a single cli option to follow every path and check everything Of course I would advocate and assume that programmers would want that to be the default... But anyway I hope this feedback is at least a little useful, thanks |
-- Sorry, I misrepresented that first quote:
Yes the branches are 100% dead. This is true I guess I'm trying to say this is just in the current binary, but it is not dead to the programmer, nor is it dead to future binaries as the programmer updates the code -- The code I am updating generally has the most dead branches, and is also the place I most need typechecking |
I suggest that these should be compile time errors. A real usecase is for importing a file such as std/c/dragonfly.zig, and not having a test case for each define
I stopped using scheme in the past because an accidental typo landed in a rarely tested code-path, and it took weeks before it was discovered. On the other hand I guess zig compile time is faster by skipping dead code, but shouldn't a sensible program have little dead code
valid.zig:
import.zig:
The text was updated successfully, but these errors were encountered: