Giter VIP home page Giter VIP logo

Comments (4)

InKryption avatar InKryption commented on May 29, 2024

What happens to a labelled defer inside of a loop?

from zig.

jklw10 avatar jklw10 commented on May 29, 2024

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.

rohlem avatar rohlem commented on May 29, 2024

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 for errdefer).
  • 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.

DerpMcDerp avatar DerpMcDerp commented on May 29, 2024

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 bools 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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.