5 ms·
The short lifetime of most objects should be implicit from scope and obvious to the programmer. It's usually easier that way, and certain GC-based languages end
by veltas 5y ago
The short lifetime of most objects should be implicit from scope and obvious to the programmer. It's usually easier that way, and certain GC-based languages ended up adding special syntax to add that level of control for objects when the programmer wants fine-grained control over the destructor.
And on the other hand, optional GC is something non-GC languages can end up adding too, like C++. Garbage collection is required (or convenient) for some problems, cleaning up objects that would be leaked by reference counting or weaker strategies.
EDIT: deemphasised universality of this rule, not really important to my point anyway: that GC/non-GC memory management are more orthogonal than they appear from language feature discussions, in theory. I wasn't trying to imply literally "all" such languages add these features, I have just noticed a number of relevant cases.
- johnny22 5y agodidn't they remove GC from C++?
- veltas 5y agoI honestly don't know, maybe. There are libraries for it too though. https://hboehm.info/gc/ https://hboehm.info/gc/
- josephg 5y agoHuh? Which languages are you referring to? Javascript, Lua, Python and ruby are all GC based languages with (as far as I know) no special syntax for short lived objects. Does Go have syntax like that? The only GC language I can think of with special stack variables is C#. Are there others? Does Java do this now? And on the other side, I’ve still never seen a production C or C++ codebase which used a garbage collector. The closest I’ve seen is refcounting - but that’s a very different beast compared to what V8, .net, Go, etc do internally to garbage collect objects. The only languages I’ve seen which mix GC and non-GC code are D, Nim (I think), with an honourable mention for Obj-C / Swift’s ARC. But again, I’m not sure ARC belongs in the same category as the generational GCs we see in the JVM and others. With a few obscure exceptions, it seems to me that the gc/ non-gc line is still pretty firm for most programming languages.
- veltas 5y agoLua for instance has specific syntax added for it: https://www.lua.org/manual/5.4/manual.html#3.3.8 https://www.lua.org/manual/5.4/manual.html#3.3.8 Languages tend to have workarounds or conventions for this kind of code where there isn't special syntax for it: https://stackoverflow.com/a/865272 https://stackoverflow.com/a/865272 (Python) Also just because C or C++ codebases don't use GC doesn't mean it's not useful. I've never used it either, but I can think of situations where I would use it. Like I've not used most of the algorithms I learned at uni but I can still think of where I might use them.
- p_l 5y agoI can think of only Common Lisp, which has optional optimization hint that specific object won't get passed outside of current stack (declaring something DYNAMIC-EXTENT, to be specific). Mind you, it's only a hint, and there were specific techniques for writing "nonconsing" code (in Lisp lingo, "non-allocating", thus not creating garbage)
- hayley-patton 5y agoNote that "short lived objects" and "stack allocated objects" aren't exactly the same set. Common Lisp has a dynamic-extent declaration, which can be used to stack allocate [1]. Go and Java implementations perform escape analysis. There can have some wins if stack allocatability is tracked at runtime, rather than compile-time [2]; Cliff Click reported roughly doubling the number of stack-allocated objects by using escape detection rather than analysis [3]. At least the Inkscape vector editor uses the Boehm garbage collector [4]. There are several programming language implementations which use Boehm and C, but one wonders if it is still a "C codebase" then. [1] http://www.lispworks.com/documentation/HyperSpec/Body/d_dynami.htm http://www.lispworks.com/documentation/HyperSpec/Body/d_dyna... [2] Henry Baker, CONS should not CONS its arguments https://www.cs.tufts.edu/~nr/cs257/archive/henry-baker/cons-lazy-alloc.pdf https://www.cs.tufts.edu/~nr/cs257/archive/henry-baker/cons-... [3] https://youtu.be/5uljtqyBLxI?t=791 https://youtu.be/5uljtqyBLxI?t=791 [4] http://inkscape.gitlab.io/inkscape/doxygen/namespaceInkscape_1_1GC.html http://inkscape.gitlab.io/inkscape/doxygen/namespaceInkscape...
- 5y ago
- barrkel 5y agoShort lifetime is not usually implicit from scope, in languages with GC. Function return values are the problem and solving this problem is the primary ergonomic of GC which in turn affects the style of code written. If you allocate a value to return, you don't in general know how it will be deallocated because that depends on the caller. The caller may use it for a short time (so stack allocation could work) or store it in the heap where it will have indefinite lifetime. This is why it's not implicit from the scope. Data flow compounds the problem: if references to arguments to the function are stored in the allocated return value, then the return value extends their lifetime, but again, the writer of the function doesn't know by how much. Simple refactoring which abstracts code into more reusable functions will obscure local reasoning about allocation. Working around these problems in the absence of GC or lifetime analysis means adopting various ad-hoc fixes, like calling conventions which pass the location for the return value as a hidden parameter, or smart pointers which dynamically track ownership, or coding conventions like caller always allocates, or global conventions like zone allocation. The big programming ergonomic side-effect of the presence of GC is the ability to more freely write and refactor functions that allocate and freely reuse them elsewhere. Conversely, code written without GC will be less factored into reusable functions. Rust's lifetime management is somewhere in the middle. It requires particular conventions and if you're able to follow the conventions then ergonomics approach that of GC. But if you want cyclic data structures, or to simply pass data which might enable the construction of cyclic data structures, you need to think harder.