3 ms·
Very interesting blog. Trying not to go too much off-topic here, I read in one of your posts that "Awk and shell are similar in an interesting way: they lack ga
by dangom 10y ago
Very interesting blog.
Trying not to go too much off-topic here, I read in one of your posts that "Awk and shell are similar in an interesting way: they lack garbage collection. This leads to arrays that can neither be nested nor returned from functions."
Would you be willing to explain why that is the case? I'm a CS enthusiast without any formal CS education.
- theoh 10y agoNot the author, but I'll have a shot: I think the problem is with responsibility for memory allocation and freeing. To dispose of a nested array's memory, you would need to follow all of its pointers to an arbitrary depth, or, alternatively, keep track of every reference in the program (and garbage collect "dead" arrays). Arrays can't be returned from a function if they're allocated on the heap, or to put it more abstractly, if you returned an array you would lose the ability to straighforwardly limit its lifetime by tying it to the function's scope. (Conventionally, functions free all their "local" storage on returning.) So, in the absence of both manual memory management (e.g. malloc and free) and garbage collection, you can't allow an array to be returned from a function, or cope with nested arrays without special support from the language.
- chubot 10y agoAnother way to say it is the bash and awk have no references, and hence no aliasing (and no possiblity of cycles). Consider: d = [1,2,3] e = {key1: d} Now you have an two names for the array [1,2,3] -- d and e['key1']. They are aliases. Now consider something like this: f() { d = [1,2,3] g(d) # The interpreter has no idea what this does, without runtime inspection e = {key1: d} return e } How do you figure out how to free memory? There's no way to do it without garbage collection, which is an algorithm that runs concurrently with your program. For contrast, Rust eliminates the runtime bookkeeping with compile time annotations like borrowing. So basically if you have references and aliasing, and you can move them across function boundaries, then you must have garbage collection if you want to free memory automatically. (Function boundaries are important, because they use the idea of a stack. A stack is a (limited) way to automatically manage memory.) But bash and awk both get around this by not having references. This eliminates the possiblity of nested compound data structures, or returning values by reference. But in return you don't have to implement a garbage collector. Compound data structures are flat and confined within a stack frame. (You could still copy the whole array to another function's stack frame if you wanted, but they don't do that.) So you can't express that program in either bash or awk. They have "flat" hash tables and arrays, where you can only COPY primitive values like ints and strings into them. You can't reference other arrays like {key1: d}. Hopefully that helps. I hacked on awk a bit here [1] and that is when I noticed the limitations in the language. I thought it was sort of like JavaScript -- regexes and hash tables. But it's actually much more limited, due to its lack of garbage collection. [1] https://github.com/andychu/bwk https://github.com/andychu/bwk