anchor.diff:                  | 1 -> inlineLet expr var value body
                   | _ -> expr
           | Sequential (a, b) when isMostlyPure a -> b
  -        | FieldGet (NewObject fs, Constant (String fieldName)) ->
  -            let mutable nonPureBefore = []
  -            let mutable nonPureAfter = []
  -            let mutable fieldValue = None
  -            for n, v in fs do
  -                if n = fieldName then
  -                    fieldValue <- Some v
  -                else 
  -                    if not (isMostlyPure v) then
  -                        match fieldValue with
  -                        | None -> nonPureBefore <- v :: nonPureBefore
  -                        | _ -> nonPureAfter <- v :: nonPureAfter
  -            let fieldValue = defaultArg fieldValue (Constant Undefined)
  -            let result =
  -                Seq.fold (fun e v -> Sequential (v, e)) fieldValue nonPureBefore 
  -            if List.isEmpty nonPureAfter then
  -                result 
  -            else 
  -                let resVar = Id fieldName
  -                Let (resVar, result, 
  -                    Seq.fold (fun e v -> Sequential (v, e)) (Var resVar) nonPureAfter
  -                )
  -        | FieldGet (NewArray fs, Constant (Integer index)) ->
  -            let mutable nonPureBefore = []
  -            let mutable nonPureAfter = []
  -            let mutable fieldValue = None
  -            let mutable i = 0
  -            for v in fs do
  -                if i = int index then
  -                    fieldValue <- Some v
  -                else 
  -                    if not (isMostlyPure v) then
  -                        match fieldValue with
  -                        | None -> nonPureBefore <- v :: nonPureBefore
  -                        | _ -> nonPureAfter <- v :: nonPureAfter
  -                i <- i + 1
  -            let fieldValue = defaultArg fieldValue (Constant Undefined)
  -            let result =
  -                Seq.fold (fun e v -> Sequential (v, e)) fieldValue nonPureBefore 
  -            if List.isEmpty nonPureAfter then
  -                result 
  -            else 
  -                let resVar = Id ("item" + string index)
  -                Let (resVar, result, 
  -                    Seq.fold (fun e v -> Sequential (v, e)) (Var resVar) nonPureAfter
  -                )
           | _ -> expr
   
       // keep rewriting with `step` bottom-up until reach a fixpoint
  
positive.code:                     | Var v when v = var -> false
                      | _ -> Children e |> List.forall alwaysInterop  
                  if alwaysInterop body then
                      Let(var, jsFunc |> tr |> WithPosOf value, body |> BottomUp (function WithInterop -> Var var | e -> e) |> tr)
                  else tr expr
              match value with
              | TupledLambda (vars, lBody) ->
  
negative.code:         let tr = Transform clean
          match expr with
          | Application (Call (Runtime, Constant (String "Bind"), [f; obj]), args) ->
              Call(clean f, !~(String "call"), (obj :: args) |> List.map clean)
          | Call (Call (Runtime, Constant (String "Bind"), [f; obj]), Constant (String "apply"), [args]) ->
              Call (clean f, !~(String "apply"), [clean obj; clean args])
          | Call (Runtime, Constant (String rtFunc), xs) ->
              match rtFunc, xs with
              | "CreateFuncWithArgs", [ TupledLambda (vars, body) as f ] ->
                  Lambda(None, vars, clean body) |> WithPosOf f
              | "CreateFuncWithOnlyThis", [ Lambda (None, [obj], body) as f ] ->
                  Lambda (Some obj, [], clean body) |> WithPosOf f   
              | "CreateFuncWithThis", [ Lambda (None, [obj], Lambda (None, args, body)) as f ] ->
                  Lambda (Some obj, args, clean body) |> WithPosOf f   
              | "CreateFuncWithThisArgs", [ Lambda (None, [obj], TupledLambda (vars, body)) as f ] ->
                  Lambda(Some obj, vars, clean body) |> WithPosOf f
              | "CreateFuncWithRest", [ Constant (Integer length); TupledLambda (vars, body) as f ] ->
                  let rest :: fixRev = List.rev vars
                  let fix = List.rev fixRev
                  Lambda (None, fix, Let (rest, sliceFromArguments [ length ], clean body)) |> WithPosOf f
              | "SetOptional", [obj; field; optValue] ->
                  match optValue with
                  | NewObject ["$", Constant (Integer 0L)] ->
                      FieldDelete (clean obj, clean field) |> WithPosOf expr
                  | NewObject ["$", Constant (Integer 1L); "$0", value] ->
                      FieldSet (clean obj, clean field, clean value) |> WithPosOf expr
                  | _ -> tr expr     
              | "NewObject", [NewArray keyValuePairs] ->
                  let withConstantKey =
  