Linear types corresponds to linear logic and ensures that objects are used exactly once, allowing the system to safely deallocate an object after its use.
Neal wrote to me about this. Can we do linear types in Shen? Generally it is easy to add to Shen, but sometimes you need to remove features if what you want to do is inconsistent from the underlying system. Shen gives (enable-type-theory -) for Shenturians who want to experiment like this. Linear logic is different enough to warrant seeing how to do this.
We use Shen sequent calculus to rebuild the type system from scratch. The key is that we keep control of the hypothesis list ourselves and we avoid branching in our type proofs by keeping the problems on our own stack.
Let's first see how this works for the non-linear case. Here is the program in sequent calculus.
(datatype nonlinear
____________________________
(enable-type-theory +) : boolean; \\ so we can back to reality!!
\\ this rule just grabs the type problem from the
\\ checker and sends it to our system placing the problem
\\ and the type onto stacks
!; (() (X) (A));
________________
X : A;
\\ if the stack of problems is empty we're done;
_________________
(_ () _);
\\ solve by hypothesis
(member (P A) Hyps);
(Hyps Rest B);
____________________________
(Hyps (P | Rest) (A | B));
___________________
(member X (X | _));
(member X Hyps);
_____________________
(member X (_ | Hyps));
\\ solve N : number if N is a number
if (number? N)
(Hyps Rest B);
_______________________________
(Hyps (N | Rest) (number | B));
\\ solve using the type of +
(Hyps Rest B);
_____________________________________________
(Hyps (+ | Rest) ((number --> (number --> number)) | B));
\\ solve if an application
(Hyps (F X | Y) ((A --> B) A | C));
________________________________________
(Hyps ((F X) | Y) (B | C));)
Let's give this a go.
(1+) (enable-type-theory -)
false : boolean
(2+) (+ 6)
#<CLOSURE (LAMBDA (V2081)) {100451DC4B}> : (number --> number)
(3+) (+ 6 7)
13 : number
(4+) (* 6 7)
type error
Weird. Let's get into our old reality.
(5+) (enable-type-theory +)
true : boolean
(6+) (* 6 7)
42 : number
Now let's try a linear type theory in which assumptions are bounded resources and can only be used once.
(datatype linear
____________________________
(enable-type-theory +) : boolean; \\ so we can back to reality!!
\\ this version adds a hypothesis about *
!; (((* (number --> (number --> number)))) (X) (A));
________
X : A;
_________________
(_ () _);
\\ hypotheses are removed when used
(remove (P A) Hyps NewHyps);
!;
(NewHyps Rest B);
____________________________
(Hyps (P | Rest) (A | B));
___________________
(remove X (X | Hyps) Hyps);
(remove X Hyps NewHyps);
_____________________
(remove X (Hyp | Hyps) (Hyp | NewHyps));
if (number? N)
(Hyps Rest B);
_______________________________
(Hyps (N | Rest) (number | B));
(Hyps Rest B);
_____________________________________________
(Hyps (+ | Rest) ((number --> (number --> number)) | B));
(Hyps (F X | Y) ((A --> B) A | C));
________________________________________
(Hyps ((F X) | Y) (B | C));)
Let's give it a whirl.
(9+) (preclude [nonlinear])
[type#linear] : (list symbol)
(10+) !1
(enable-type-theory -)
false : boolean
(11+) (* 6 7)
42 : number
(12+) (* 6 (* 7 8))
type error
This fails because we tried to use the same hypothesis twice. Really weird- time to exit this linear reality!
(13+) (enable-type-theory +)
true
(14+) (preclude [linear])
[] : (list symbol)
and we're back.
Mark