Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

References and memory leaks #55

Open
TheLoneWolfling opened this issue Jul 13, 2016 · 6 comments
Open

References and memory leaks #55

TheLoneWolfling opened this issue Jul 13, 2016 · 6 comments

Comments

@TheLoneWolfling
Copy link
Collaborator

So. I've been puttering around starting to deal with making sure that Huo doesn't leak memory like a sieve, and have hit upon a problem. Namely, arrays.

It's generally pretty clear when to free a value. However, since arrays in values are referenced by reference, instead of by value, one can have multiple references to an array. This means that we cannot just always free the array when freeing a value (of type array).

Normally, this is dealt with in one of two ways. Either through reference counting, or via garbage collection. However, given that you want performance, neither is particularly appealing.

On a very related note, how do you wish the following to work? Or rather, what do you want it to print?

(let x [])
(let y x)
(push y 1)
(print x)

Should it print [1]? Or []?

@TheLoneWolfling
Copy link
Collaborator Author

We can, I suppose, limit refcounting to arrays only.

@TheLoneWolfling
Copy link
Collaborator Author

Copying in @incrediblesound's https://github.com/HuoLanguage/huo/issues/52#issuecomment-232427437:

@TheLoneWolfling that relates to your question in #55. I think we should opt for immutable arrays. So:

(let x [])
(let y x) ; y is now a copy of x
(push 1 y) ; y = [1] and x = []
(let z [1, 2, 3])
(let a (map z item index (* item item)))
; z = [1, 2, 3] and y = [1, 4, 9]

But that makes me wonder, should we allow the simple assignment of arrays at all? Perhaps that should throw an error, especially since copying nested arrays would be costly. Maybe we can have a copy function to make it explicit:

(let x [1, 2, 3])
(let y (copy x))

Does that sound good to you @TheLoneWolfling ?

@TheLoneWolfling
Copy link
Collaborator Author

And my response:

That could work. Call and reference by value, in other words.

(Though note that what you are suggesting is not immutable arrays. If it was, (push 1 y) would return a new array with 1 pushed to it, and y wouldn't have changed.)

If you have something like this:

(f (index (index (index x 1) 2) 1))
(g (index (index (index x 1) 2) 2))
(h (index (index (index x 1) 2) 3))

You cannot pull the common index subexpression out into a let definition, which could be annoying.

I'd prefer not to require a copy function, though. It'd end up being used so often that it'd just end up being syntactic noise.


I don't see how this deals with #55, however.

Consider what happens when you pass an array to this:

(def f x (g x x))

where g is another function. You'll end up with multiple references to the same array, which is the exact problem we're trying to avoid. Unless you're talking about making an array copy at every function call for every array parameter, which would be absurd (and wouldn't allow you to do many things in functions, to boot).

@TheLoneWolfling
Copy link
Collaborator Author

Your thoughts, @incrediblesound?

@incrediblesound
Copy link
Member

I'll try to get to this today, been a little busy of late :-/

@TheLoneWolfling
Copy link
Collaborator Author

That's fine, and I understand. I have been busy too (read: looking for work).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants