```//
// An introductory example to linear types in ATS
//

(* ****** ****** *)

extern praxi ptr_view_conversion
{a1,a2:viewt@ype | sizeof a1 == sizeof a2} {l:addr}
(pf: !a1? @ l >> a2? @ l): void

fn{a1,a2:viewt@ype | sizeof a1 == sizeof a2} swap {l1,l2:addr}
(pf1: !a1 @ l1 >> a2 @ l1, pf2: !a2 @ l2 >> a1 @ l2 | p1: ptr l1, p2: ptr l2)
: void = let
val tmp = !p1
prval () = ptr_view_conversion {a1,a2} (pf1)
val () = !p1 := !p2
prval () = ptr_view_conversion {a2,a1} (pf2)
val () = !p2 := tmp
in
// empty
end // end of [swap]

(* ****** ****** *)

implement main () = let
typedef T = int
var x1: T = 1 and x2: T = 2
val () = printf ("x1 = %i and x2 = %i\n", @(x1, x2))
val () = swap<T,T> (view@ x1, view@ x2 | &x1, &x2)
val () = printf ("x1 = %i and x2 = %i\n", @(x1, x2))
typedef T = double
var x1: T = 1.0 and x2: T = 2.0
val () = printf ("x1 = %f and x2 = %f\n", @(x1, x2))
val () = swap<T,T> (view@ x1, view@ x2 | &x1, &x2)
val () = printf ("x1 = %f and x2 = %f\n", @(x1, x2))
in
// empty
end // end of [main]

(* ****** ****** *)

(* end of [linear101-2008-11-06.dats] *)
```