Comments (4)
What happens to a labelled defer inside of a loop?
from zig.
I'd assume it would just do it at the end of current loop iteration. if i wanted to move the defer outside of it i would wrap the whole loop in another block to defer to that.
from zig.
The main hurdle in implementing this feature is the compilation / optimization semantics compared to status-quo.
- By always attaching (
err
-)defer
-ed statements to the current block in status-quo, it becomes a relatively trivial task of shuffling code around for the compiler:
You're telling it "put this code into the block that is run when exiting this current block (via error return forerrdefer
). - Allowing (
err
-)defer
-ed statements to outer blocks behind runtime branching instead means "attach this code to a runtime-determined list of code that is run when this outer block exits".
Because source code is (usually) not executed 1:1, but goes through many layers of translation,
the current "static" nature helps giving guarantees and freedom to the various optimization passes to
inline, merge, reorder the accumulated statements - as single "ok-exit" and "error-exit" blocks.
With the proposed runtime-decided nature introduced via runtime-branching however,
since every inner block has its own list of statements, only those couple statements can be analyzed that effectively,
and the exit blocks will (virtually) always have to include additional branching.
In the case of loops, where multiple iterations may execute defer
-s, we now also need a loop in the exit blocks.
(It's also not quite clear whether you're allowed to include, for example, the loop counter in the defer statement -
meaning the defer
becomes a closure that has to save the value somewhere to the stack - or not.
No such ambiguity with the limited feature of status-quo.)
For while
-loops, because their executions aren't numerically bounded, that is a potentially-unbounded number of
elements making up this exit block - meaning we have an unbounded number and unbounded exit block growth.
Those are even more elements complicating language implementation,
loosening the guarantees programmers can expect from the language.
(For Zig it's certainly easier, and probably less controversial, not to solve issues
with such non-trivial implementation strategies with different tradeoffs by a language feature,
and instead burden programmers to come up with a solution to their particular use case in userspace.)
The current "static" approach is also simpler to reason about for someone reading the code
than parsing where (in which outer block) which defer
-s are going to run how many times
(potentially, if the respective runtime code path was taken).
blk: {
defer f();
if (...) {
// (... arbitrary number of lines ...)
}
g();
}
Under status-quo, even without looking at any nested scopes we know that
if g()
was executed, f()
will execute next.
With this proposal, we would instead have to scan through all nested scopes for whether
any of them defer
something to :blk
, which would execute in-between.
(To be honest, I'm not convinced that a language can (or should) ever prevent you
from your code getting too complicated, so this last point doesn't personally convince me as much as the rest,
but not having this feature means there is this one less feature for
someone else's code structure to employ surprising behavior.)
from zig.
Under status-quo, even without looking at any nested scopes we know that if g() was executed, f() will execute next.
Under the status-quo you'd be lost in a maze of code and bool
s manually keeping track of whether or not to call the defer
and wondering if you got it correct.
With this proposal, we would instead have to scan through all nested scopes for whether any of them defer something to :blk, which would execute in-between.
But the code would be smaller and known to be correct since it's managed by the compiler.
(It's also not quite clear whether you're allowed to include, for example, the loop counter in the defer statement - meaning the defer becomes a closure that has to save the value somewhere to the stack - or not. No such ambiguity with the limited feature of status-quo.)
The defer
doesn't capture variables. Though I suppose the following syntax:
:blk {
{
defer :blk |some_capture| something(some_capture);
}
}
=>
:blk {
flag: u32 = 0;
some_capture_gensym: whatever;
{
some_capture_gensym = some_capture;
flag |= 1;
}
if (flag & 1)
something(some_capture_gensym);
}
could be used to capture any variable it needs.
For while-loops, because their executions aren't numerically bounded, that is a potentially-unbounded number of elements making up this exit block - meaning we have an unbounded number and unbounded exit block growth.
The defer
blocks don't accumulate.
from zig.
Related Issues (20)
- `error: TODO: implement @ptrCast between slices changing the length`
- Compiler allows initialisation of enum types with invalid enum Values HOT 1
- Runtime safety check added in comptime block HOT 2
- Cannot `@cImport` `windows.h` when targetting `msvc` abi HOT 5
- Errdefer payload type doesn't match function signature
- `callconv(.Naked)` functions with parameters cause silent LLVM crash when compiling for PowerPC
- default local cache directory to `.zig-cache` instead of `zig-cache` HOT 4
- std.debug.bufPrintZ padding on the wrong side of output
- observed error.Unexpected NTSTATUS=0xc0000056 (DELETE_PENDING) in makeOpenDirAccessMaskW
- add `math.approxEqUlp` for numerical precision testing
- Missing error for runtime `@ptrFromInt` to comptime-only type HOT 2
- ReleaseSafe panic error trace points at line 0 when freeing an undefined pointer HOT 4
- Zig does not report errors or sliently fails on `.S` / `assembler_with_cpp` files
- Can't link on PPC64LE HOT 1
- ErrorUnion typeInfo debug print causes GenericPoison HOT 2
- @cInclude("stdio.h") doesn't work for -Dtarget=wasm32-emscripten
- Unsure how to handle duplicate symbol linker error
- SIGTRAP When attempting to write to a runtime index in comptime variable HOT 1
- Undefined struct fields are initialized to 0 instead of 0xAA in debug mode (with llvm backend)
- zig fetch -h should include examples
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from zig.