Lively Linear Lisp – 'Look Ma, No Garbage' (1991)
home.pipeline.com
home.pipeline.com
https://github.com/pikatchu/LinearML
Development kinda stopped after the author joined FB. Hoping for a revival.
If we assume some sort of object orientation, or first class functions are available, affine types become (I think) impossible; If a value T with lifetime 'a is handed to a completely unknown method on an unknown object, or to an arbitrary lambda, we can't prove that the method will not destroy T in the middle of lifetime 'a. In otherwords, if typechecking is ruled out, we cannot do borrowchecking either.
[0] https://www.reddit.com/r/rust/comments/4mdgux/rust_and_affin...
As an example, compare two languages: one with linear types and one with affine types. Let's say that you had a "File" type, a function "open()" that creates a file (either linear or affine as appropriate), and a function "close()" that consumes the file. Then this code would be legal in both languages with linear types and languages with affine types:
let f: File = open()
close(f)
Note that "f" is used once and only once, at which point the value is consumed. In a language with affine types, this is also kosher: let f: File = open()
// Do nothing
This fails to compile in the language with linear types because "f" is never used. Finally, this code is never legal in either language: let f: File = open()
close(f)
close(f)
... because "f" is used twice here, and neither linear types nor affine types allow that.So affine types give you a little more leeway.
In a purely functional language with affine types, unused variables are usually just optimized out.
open : () -> File
close : File -> ()
write : (File, String) -> File
let f: File = open()
let new_f : File = write(f, "Hello world!\n")
close(new_f)
If this seems clumsy or error-prone, notice that you can't accidentally close() f instead of new_f, and you can't forget to close() new_f, so there is actually very little room for error here.In practice I don't know if anyone is overly concerned about this. While Rust doesn't have linear types, I find you have to bend over backwards to introduce a situation where you might accidentally leak a resource.
Tarean makes a good point with respect to fusion, but "guaranteeing" fusion requires additional assistance from the compiler in addition to the basic implementation of linear types.