[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Let deprecate to-be-close variables as harmful concept
- From: Lars Müller <appgurulars@...>
- Date: Tue, 3 Oct 2023 14:16:26 +0200
  
  
    I've roughly seen four concepts for resource management:
      
      (0. No language support, do it yourself. Error-prone; often only
      code for the "happy path" is written (so errors that don't
      terminate the application result in resource leaks).)
      1. "with" blocks. In Python this is a statement with a block
      scope. In languages like Lua, this can be implemented using
      closures (for example, in Lua 5.1 I use a with_open akin to
      Scheme's with-(input|output)-(from|to)-file).
    2. "defer" statements, as found e.g. in Go or Zig, which run in
      reverse order when the function (Go) or scope (Zig) is left
      (normally or with an error).
    
    3. SBRM (Scope-Bound Resource Management) like Lua's
      to-be-closed variables: Resources are released when the
      corresponding variables go out of scope.
    
    4. Reference counting, which ensures that resources are released
      when they aren't needed any more, no matter how contrived the
      program logic. Works as long as there are no reference cycles
      among resources (which there practically almost never are). The
      special case of 0-1-reference counting can to a large extent be
      done by "ownership" models like Rust's, but those are very much
      out of scope for Lua.
    
    
      I think 3. is the best option for Lua here: 
      
      1. Becomes awkward as the more resources you use, the deeper your
      nesting goes. The closure-based approach has the shortcomings of
      function usage (for example not allowing break).
      2. This is a pretty decent solution; it is slightly more verbose
      however (another statement). I also don't like tying this to
      block- or function scope; this means in practice resources will
      live longer than they have to if the programmer (say, the
      function/block does some expensive computation after being done
      with the resource; the resource will only be released after that).
      It has the small advantage vs. to-be-closed variables that you
      need less boilerplate if you have cleanup code that naturally
      isn't tied to an object.
      3. The best solution for Lua, IMO. Very concise - just add
      "<close>" after the resource variable name. Definitely much
      better than the error-prone "local f = io.open(...); [...];
      f:close()" antipattern, which won't clean up immediately if the
      "[...]" throws an error that is caught later on. Let's the
      compiler figure out for you when you last use a variable (and when
      it is thus safe to clean it up).
      4. Not really an option for Lua, since Lua doesn't base
      its garbage collection on reference counting; not using RC is
      presumably also better for performance, and is simpler than having
      to use something like a RC + tracing/generational GC approach to
      collect reference cycles.
      
      There's also the case of iterators - like io.lines - having to do
      cleanup. Prior to 5.4's introduction of the to-be-closed iterator
      variable for the generic for loop, pretty much the best solution
      for this was to pass a closure, with all the downsides this has
      (for example, inside a closure, you can't return from the
      enclosing function, and you can't break an enclosing loop; also
      comes at a performance cost).
      
      The only main downside of to-be-closed variables I see at the
      moment is that it interferes with tail calls. I think the simplest
      solution would be to always close all to-be-closed variables
      before tail calling, preserving the simple rule that "return
      f(...)" is always a tail call.
      
      In principle, reference counting is the cleanest solution in my
      opinion, but it would come at a performance cost and much more
      complexity than to-be-closed variables.
    
    
    I don't really see how "
[t]his implementation
                  creates more problems than [it] solve[s]". Some
                  complexity is necessary; programmers need to think
                  about resource management.
                  It solves the problem of simple resource management
                  pretty cleanly. You can now properly work with a file
                  and all you have to do for that is add <close>
                  after a variable name.
                  In more complex scenarios, programmers might of course
                  introduce bugs. But I would argue that they probably
                  (1) introduced even more bugs before this feature
                  existed, due to forgetting to release resources (esp.
                  on error!), and
                  (2) if they wrote their code very carefully to handle
                  resource management, they just don't need to
                  use to-be-closed variables;
                  they can stick with whatever pure Lua constructs they
                  have developed.
      
      - Lars
      
      On 03/10/2023 09:27, 
kovserg33@gmail.com wrote:
    
      
      To be close variable ( https://www.lua.org/manual/5.4/manual.html#3.3.8
        ) in form it implemented is harmful by nature.
      
      They introduces unnecessary
              complexity. This implementation creates more problems than they
                    solve.  It will lead to
                    bugs on all levels. Even more this problems will be
                    hard to find and debug.
      
      Let me show
                    small example:
      [...]
      
      Variables
                    are not automatically be closed. You have to trace
                    this manually EVERY time. It's like manually
                    coloring for variables. Any if any color doesn't
                    match it will works not as expected. Absolutely
                    pointless activity. It will be worse if code base
                    will grow and number of programmers will increase.
                    Any changes will cause pain every time they be
                    applied.
                  
      More over
                    every thing to manage resource lua has before
                    version 5.4. One possible solution for resource
                    management is 
                  
      https://raw.githubusercontent.com/kov-serg/lua-aux/master/proto-seq_fn.lua
                  
      Have any reasonable objections?