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

Lifetimes #173

Closed
bvssvni opened this issue May 16, 2016 · 2 comments
Closed

Lifetimes #173

bvssvni opened this issue May 16, 2016 · 2 comments

Comments

@bvssvni
Copy link
Member

bvssvni commented May 16, 2016

Dyon uses a lifetime checker instead of a garbage collector. This adds a little more work to get the program running, but makes it easier to run the program. There are no pauses to clean up unused memory, just full steam ahead with predictable performance.

In Rust a lifetime is declared separately from arguments. Dyon uses argument names to describe lifetimes.

a: 'b means a outlives b

a: 'return means a outlives the return value of the function.

What are lifetimes?

For example, consider the following program:

fn foo(mut a, b) {
    a.x = b
}

fn main() {
    a := {x: [0]}
    b := [5]
    foo(mut a, b)
}

Dyon won’t let you run it, because storing b inside a requires it to outlive a:

Function `foo` requires `b: 'a`
2,11:     a.x = b
2,11:           ^

The b variable must be declared before a in stack memory. Or else when the stack rolls back, then a points to memory that is outside the valid memory, a dangling pointer.

One way to fix it is to write clone(b), but you can also do as Dyon says:

fn foo(a, b: 'a) {
    a.x = b
}

Now there is another error:

`b` does not live long enough
8,16:     foo(mut a, b)
8,16:                ^

This is because b is declared after a:

fn main() {
    a := {x: [0]}
    b := [5] // `b` does not outlive `a`
    foo(mut a, b)
}

By moving it before a, the program works:

fn main() {
    b := [5] // `b` outlives `a`
    a := {x: [0]}
    foo(mut a, b)
}
@naasking
Copy link

In one sense, this approach seems problematic because it leaks the function's implementation details. Then again, Rust already leaks this information with its lifetimes.

In another sense, this is a syntactically neat approach to specifying lifetimes, reminiscent of region-based memory management. How has the experimentation with this feature gone? Have you tried eliminating lifetime annotations entirely and just requiring the programmer to conform to the stack convention?

I can see it being fairly easy to write a program, but changing the function's internals could cause surprising non-local breakages, which is particularly problematic given Dyon is dynamically typed.

Traditional named arguments would solve this problem if named arguments were required for all calls, but Dyon's named arguments are unusual enough that I'm not sure if they would solve this issue.

@bvssvni
Copy link
Member Author

bvssvni commented Dec 12, 2016

I almost never use lifetimes. The lifetime checker helps me add clone at the right places, or move the order a bit to save some operations. Otherwise, it is strange how rare lifetimes are needed. I am quite happy with the current implementation. More information http://www.piston.rs/dyon-tutorial/lifetimes.html

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

No branches or pull requests

2 participants