anchor.diff:  
           new(stream : Stream) = new AssemblerStream(stream, false)
   
  -
  +[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
   module AssemblerStream =
       let ofStream (s : IO.Stream) =
           match sizeof<nativeint> with
  
positive.code:                     x.Pointer.Write(off, 0xE9uy)
                      x.Pointer.Write(off + 1, offset)
                  else
                      let off = x.Pointer.Size - jumpSize |> int
                      x.Pointer.Write(off, 0xC9uy)
                      x.Pointer.Write(off + 1, 0xC3uy)
  
negative.code:         interface IDisposable with
              member x.Dispose() = x.Dispose()
  
          new(data : alist<'a>, compile : Option<'a> -> 'a -> IAssemblerStream -> unit) = new NativeProgram<'a>(data, true, compile)
          new(data : alist<'a>, compile : 'a -> IAssemblerStream -> unit) = new NativeProgram<'a>(data, false, fun _ v s -> compile v s)
      
      [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
      module NativeProgram =
          let differential (compile : Option<'a> -> 'a -> IAssemblerStream -> unit) (values : alist<'a>) =
              new NativeProgram<'a>(values, compile)
  
          let simple (compile : 'a -> IAssemblerStream -> unit) (values : alist<'a>) =
              new NativeProgram<'a>(values, compile)
  
      
  
  
      type MyDelegate = delegate of int * int * int * int -> unit
      
      type TestDelegate = delegate of int * int -> unit
  
      type TestProgram(values : alist<int>) =
          let mutable validate = false
          let store = List<int * int>(1024)
          let d = TestDelegate (fun p s -> if validate then store.Add(p,s))
          let dPtr = Marshal.PinDelegate d
  
          let program = 
              values |> NativeProgram.differential (fun prev self stream ->
                  stream.BeginCall(2)
                  stream.PushArg(self)
                  stream.PushArg(defaultArg prev 0)
                  stream.Call(dPtr.Pointer)
              )
  
          member x.AverageJumpDistance = program.AverageJumpDistance
          
          member x.Update() =
              program.Update(AdaptiveToken.Top)
              
          member x.Run() =
              program.Update(AdaptiveToken.Top)
              program.Run()
  
          member x.RunAndValidate() =
              validate <- true
              store.Clear()
              program.Update(AdaptiveToken.Top)
              program.Run()
              validate <- false
              let calls = store |> CSharpList.toArray
              let ref = values.Content |> Mod.force
              let mutable error = false
              let mutable l = 0
              let mutable i = 0
              for r in ref do
                  let should = (l,r)
                  let is = calls.[i]
  
                  if should <> is then error <- true
  
                  i <- i + 1
                  l <- r
  
              if error then
                  Log.warn "ERROR: %A vs %A" calls ref 
              else
                  Log.line "calls: %d" calls.Length
  
  
      let report =
          MyDelegate (fun a b c d ->
              Log.start "cb"
              Log.line "a: %A" a
              Log.line "b: %A" b
              Log.line "c: %A" c
              Log.line "d: %A" d
              Log.stop()
          )
  
  
      let pReport = Marshal.PinDelegate(report)
  
  
      let test() =
          let values = clist [0;1;2;3]
          let prog = TestProgram(values)
  
          
          Log.startTimed "run"
          prog.RunAndValidate()
          Log.line "dist: %A" prog.AverageJumpDistance
          Log.stop()
          
          Log.startTimed "run"
          transact (fun () -> values.Insert(2, 100))
          prog.Update()
          prog.RunAndValidate()
          Log.line "dist: %A" prog.AverageJumpDistance
          Log.stop()
          
          
          Log.startTimed "run"
          transact (fun () -> values.[2] <- 2)
          prog.Update()
          prog.RunAndValidate()
          Log.line "dist: %A" prog.AverageJumpDistance
          Log.stop()
          
          Log.startTimed "run"
          transact (fun () -> values.RemoveAt(2))
          prog.Update()
          prog.RunAndValidate()
          Log.line "dist: %A" prog.AverageJumpDistance
          Log.stop()
  
          let test = PList.ofList [0 .. 1 <<< 13]
  
  
  