How does reference counting work on a deeply nested, non cyclical object? - garbage-collection

Say you have this sort of structure, but imagine it was super deeply nested like 20 levels deep:
function getIt() {
let a = { hello: 'world' }
let b = { foo: 'bar', deeply: { nested: true } }
a.b = b
// stuff
a.b = null
return a
}
let x = getIt()
The a.b is no longer needed by the end of the function, so b can be garbage collected. There are no cyclic dependencies. What happens exactly in a reference counter to garbage collect b? Does it have to go through potentially thousands of nested objects (if b was thousands of nested objects deep) and decrement the counts on each of them, or can it just say we can tell from the structure somehow that since a.b = null that everything attached to it can be cleared. How does this work, and how is it typically optimized in a reference counting system like in Swift or others?

Related

How to conceptualize a lexical scope tree when you can have hoisted nested functions?

I am working on a compiler in TypeScript and thinking a lot about lexical scope. In particular I'm wondering about how you handle the situation where you have hoisted functions, where variables can be undefined at one point, and then defined at another point. For example:
function a() {
let d = 10
b()
return b
let g = 40
function b() {
c()
let f = 30
return c
function c() {
console.log(d, e, f, g)
}
}
let e = 20
}
const x = a()() // returns b, returns c
x() // log the variables
Here, what is the "lexical scope" inside the function c?
Is it all the variables it could possibly/potentially have access to (at some point) during possible code evaluation? (d, e, f, g)
Is it what it only will eventually be defined within its runtime context? (d, f)
Is it what won't be undefined and throw an error? (d)
Is it every combination of possible parents all at once (like a cartesian product sort of thing, times however many parents in the tree)?
etc.
At first, for a while (for many years), I thought of lexical scope as a simple tree. You had higher scopes and nested scopes, and each nested scope introduced new variables. Nice and clean, easy-peasy. But this, this throws it for a loop. Now it's like, focusing on c, there are steps of evaluation inside b, and at each step, a possible different parent scope may exist. Then a might have a suite of parent scopes too. So it is like a natural flower/tree that blossoms upward (which is hard to imagine in programming). There are more and more possible parents. What I'm thinking is, the lexical scope is the combination of every combination of parents on upward. But then how do you use this scope in a compiler?
Now I am confused. What am I supposed to use the lexical scope for in a compiler if I can't tell for a nested function what 1 scope definition it is? I assumed each nested function has 1 scope, but no, it's parents are vast and combinatory. You can only really tell what the scope is when it is bound ("binding", as opposed to "scope"). That is, at the specific step in code evaluation, what the value of the scope is.
So how do you use this information in a compiler? I can tell if a variable is in scope only seemingly if I evaluate/simulate the code running itself. Basically, how do I use this lexical scope in a compiler now with this confusion?
I was going to use it as the source of truth for what variables were defined in a nested lexical scope block. But now I can't, because I need to know at each step what the values of the variables are before I can know what the scope is. Or am I missing something?
Thinking of trying something like this:
type SiteContainerScopeType = {
like: Site.ContainerScopeType
parent?: SiteContainerScopeType
children: Array<SiteContainerStepScopeType>
declarations: Record<string, SitePropertyDeclarationType>
}
type SiteContainerStepScopeType = {
like: Site.ContainerStepScope
previous: SiteContainerStepScopeType
context: SiteContainerScopeType
declarations: Record<string, SitePropertyDeclarationType>
}
If I understand correctly the semantics described in Understanding Hoisting in JavaScript, the code can be reorganized as follows, ordering first declarations, then variable initialization and finally the rest of the expressions.
function a() {
// DECLARATIONS
let d
let g
let e
function b() {
let f
function c() {
console.log(d, e, f, g)
}
f = 30
c()
return c
}
// INITIALIZATION
e = 20
d = 10
g = 40
// EXPRESSIONS
b()
return b
}
When doing this, we find a more usual structure of having variables declared before being initialized and used.

What is the way to implement Observable other than Control.Lens.Setter in Haskell?

Control.Lens.Setter is remarkable to use Observable feature in Haskell. ( function/functor to be triggered when the value in the dataset is updated. )
However, considering the lens is not included in the standard environment, and then required to extra installation, without the lens, when I want to use just a primitive setter feature such as with a field label:
data Foo = Foo {val :: Int}
How to do this?
Does ST Monad fit this purpose?
Thanks.
It's not very clear what you're looking for here, but if you just want to update a record field, you can use the Haskell record update syntax:
x = Foo { val = 5 }
y = x { val = 42 }
This works for any record, with any number of fields, and you don't need to list all the fields, only the ones you'd like to update, for example:
data D = D { a :: String, b :: Int }
x = D { a = "foo", b = 42 }
y = x { a = "bar" } -- now y = D { a = "bar", b = 42 }
z = x { b = 43 } -- now z = D { a = "foo", b = 43 }
Keep in mind that this doesn't actually update ("change", "mutate") the values in memory, but rather creates copies of the records with all the fields equal to those of the original record, except the updated fields. Lenses work the same way, and in fact everything in Haskell does, since Haskell doesn't allow mutation at all.
I think that you're a bit confused between a few concepts; specifically, setter vs observable.
I don't know much about them, but an observable does seem to be, as you described, a way to run a function every time a value is changed. This concept does not exist in Haskell; I'm sure you could make it somehow, but it wouldn't be very useful, since (almost) every Haskell value is immutable.
By contrast, a setter is just a function which changes part of a value, the same as with Java getters and setters. The only slight complication is that in Haskell, all values are immutable (as I mentioned above), so instead of changing the value, a setter copies the value across but with the thing set. For instance, if you have a setter setName (for a record), and you invoke it with something like setName "foo" oldRecord, this will keep oldRecord as is, but return a new record with the name set to "foo". As you already know, there are other, more complex, implementations of setters, such as lenses.
You also mention ST. This is a more advanced concept; it's basically used when you have to use some sort of mutable variable locally but still retain purity (which is not very often).
Now to answer your other question: How do I use setters without lenses? Well, if you have a record like data Foo = Foo {val :: Int, val2 :: String} (your example + an extra field), and you have an old record - let's say oldRecord = Foo { val = 1, val2 = "test" }, Haskell has special setter syntax: doing oldRecord { val = 2 } will give a new record with val set to 2 - that is, it will give Foo { val = 2, val2 = "test" }. Obviously this syntax is a bit clumsy though for nested records, which is the reason lenses were invented.

Why MongooseJS is reversing the order of properties?

I've noticed that if we insert an object {a: 1, b: 2, c: 3}, in database it'll be stored as {c: 3, b:2, a: 1}. Why is MongooseJS doing this?
Is it for Performance Gain (or) some other logic?
Could anyone please explain this to me in detail?
There is no such thing as properties order in object. If the order is important for you use an array.
The for...in statement iterates over the enumerable properties of an object, in original insertion order. For each distinct property [...]
However this seems to be implementation (browser) dependant.
In objects you can't rely on order of the properties as even various iteration methods may give various results.
Ordering of properties in objects is complex, as this answer explains: https://stackoverflow.com/a/38218582/893780
Even though it's not specified in the standard, normal property keys are stored in insertion order.
Internally, Mongoose uses a faster code path when cloning objects, that reverses the property order. It basically does this:
let oldObject = { a: 1, b: 2, c: 3 };
let newObject = {};
let keys = Object.keys(oldObject);
let i = keys.length;
while (i--) {
let k = keys[i];
let val = oldObject[k];
newObject[k] = val;
}
Because normal keys are stored in insertion order, newObject will be the reverse of oldObject:
{ c: 3, b: 2, a: 1 }
However, because this can cause issues in queries, Mongoose added an option retainKeyOrder to prevent this reversal.
However, according to the same answer that I linked to above, you still can't rely on any order being imposed when using Object.keys() or for..in.

Nodejs Order of properties guarantee

Note: I am using Nodejs which may or may not have subtle differences from vanilla ECMAscript's standards.
I have always heard that when using a for-each loop to iterate over the properties of an object, I should not count on the properties being in the same order. (even though in practice I have never seen a case where the objects were iterated over in a different order). In production, we have what I believe to be a typo where an object is created with an overwritten property.
var obj = {
a: 'a property',
b: 'another property',
c: 'yet another property',
a: 'woah we have another a?'
}
In Nodejs, am I guaranteed that the second a property containing the string 'woah we have another a?' will ALWAYS shadow the first a property containing the string 'a property'?
(even though in practice I have never seen a case where the objects were iterated over in a different order)
The following should give you a different order in V8 atleast.
var obj = {
"first":"first",
"2":"2",
"34":"34",
"1":"1",
"second":"second"
};
for (var i in obj) { console.log(i); };
// Order listed:
// "1"
// "2"
// "34"
// "first"
// "second"
As discussed here
ECMA-262 does not specify enumeration order. The de facto standard is to match
insertion order, which V8 also does, but with one exception:
V8 gives no guarantees on the enumeration order for array indices (i.e., a property
name that can be parsed as a 32-bit unsigned integer).
Remembering the insertion order for array indices would incur significant memory
overhead.
Though the above says the enumeration order is not specified but that is after the object is created. I think we can safely assume that insertion order should remain consistent, as there is no point for any engine to do otherwise and alter the insertion order.
var obj = {
"first":"first",
"2":"2",
"34":"34",
"1":"1",
"second":"second",
2: "two"
};
// gives result
{ '1': '1',
'2': 'two',
'34': '34',
first: 'first',
second: 'second' }

Inconsistencies when using UnsafeMutablePointer with String or Character types

I'm currently trying to implement my own DynamicArray data type in Swift. To do so I'm using pointers a bit. As my root I'm using an UnsafeMutablePointer of a generic type T:
struct DynamicArray<T> {
private var root: UnsafeMutablePointer<T> = nil
private var capacity = 0 {
didSet {
//...
}
}
//...
init(capacity: Int) {
root = UnsafeMutablePointer<T>.alloc(capacity)
self.capacity = capacity
}
init(count: Int, repeatedValue: T) {
self.init(capacity: count)
for index in 0..<count {
(root + index).memory = repeatedValue
}
self.count = count
}
//...
}
Now as you can see I've also implemented a capacity property which tells me how much memory is currently allocated for root. Accordingly one can create an instance of DynamicArray using the init(capacity:) initializer, which allocates the appropriate amount of memory, and sets the capacity property.
But then I also implemented the init(count:repeatedValue:) initializer, which first allocates the needed memory using init(capacity: count). It then sets each segment in that part of memory to the repeatedValue.
When using the init(count:repeatedValue:) initializer with number types like Int, Double, or Float it works perfectly fine. Then using Character, or String though it crashes. It doesn't crash consistently though, but actually works sometimes, as can be seen here, by compiling a few times.
var a = DynamicArray<Character>(count: 5, repeatedValue: "A")
println(a.description) //prints [A, A, A, A, A]
//crashes most of the time
var b = DynamicArray<Int>(count: 5, repeatedValue: 1)
println(a.description) //prints [1, 1, 1, 1, 1]
//works consistently
Why is this happening? Does it have to do with String and Character holding values of different length?
Update #1:
Now #AirspeedVelocity addressed the problem with init(count:repeatedValue:). The DynamicArray contains another initializer though, which at first worked in a similar fashion as init(count:repeatedValue:). I changed it to work, as #AirspeedVelocity described for init(count:repeatedValue:) though:
init<C: CollectionType where C.Generator.Element == T, C.Index.Distance == Int>(collection: C) {
let collectionCount = countElements(collection)
self.init(capacity: collectionCount)
root.initializeFrom(collection)
count = collectionCount
}
I'm using the initializeFrom(source:) method as described here. And since collection conforms to CollectionType it should work fine.
I'm now getting this error though:
<stdin>:144:29: error: missing argument for parameter 'count' in call
root.initializeFrom(collection)
^
Is this just a misleading error message again?
Yes, chances are this doesn’t crash with basic inert types like integers but does with strings or arrays because they are more complex and allocate memory for themselves on creation/destruction.
The reason it’s crashing is that UnsafeMutablePointer memory needs to be initialized before it’s used (and similarly, needs to de-inited with destroy before it is deallocated).
So instead of assigning to the memory property, you should use the initialize method:
for index in 0..<count {
(root + index).initialize(repeatedValue)
}
Since initializing from another collection of values is so common, there’s another version of initialize that takes one. You could use that in conjunction with another helper struct, Repeat, that is a collection of the same value repeated multiple times:
init(count: Int, repeatedValue: T) {
self.init(capacity: count)
root.initializeFrom(Repeat(count: count, repeatedValue: repeatedValue))
self.count = count
}
However, there’s something else you need to be aware of which is that this code is currently inevitably going to leak memory. The reason being, you will need to destroy the contents and dealloc the pointed-to memory at some point before your DynamicArray struct is destroyed, otherwise you’ll leak. Since you can’t have a deinit in a struct, only a class, this won’t be possible to do automatically (this is assuming you aren’t expecting users of your array to do this themselves manually before it goes out of scope).
Additionally, if you want to implement value semantics (as with Array and String) via copy-on-write, you’ll also need a way of detecting if your internal buffer is being referenced multiple times. Take a look at ManagedBufferPointer to see a class that handles this for you.

Resources