anchor.diff:          (_, _, [DerivedPatterns.SpecificCall <@ foldOnRange @> 
             (_, _, [LambdaN([acc; idx], body); z; st; en]); Patterns.Var(v2)]) ->
          let tp = acc.Type
  -       let tupleTp = typeof<Number * Number>.GetGenericTypeDefinition().MakeGenericType(tp, tp)
  -       let newAcc = new Var(utils.newVar acc.Name, tupleTp) 
  -       let newAccExpr = Expr.Var(newAcc)
  -       //let newAccNormal = <@@ fst (%%newAccExpr) @@>
  -       let newAccNormal = MakeCall <@ fst @> [newAccExpr] [tp; tp]
  -       //let newAccDiff = <@@ snd (%%newAccExpr) @@>
  -       let newAccDiff = MakeCall <@ snd @> [newAccExpr] [tp; tp]
  -       let accd = MakeDVar(acc)
  -       let dx = Expr.Var(v2)
  -       let newBody = 
  -         Expr.Let(acc, newAccNormal, 
  -           Expr.Let(accd, newAccDiff, 
  -             //<@@ %%body, diff %%body %%dx @@>
  -             Expr.NewTuple([body; Diff body dx])
  -           )
  -         ) 
  -       let newF = LambdaN([newAcc; idx], newBody ) 
  -       let newZ = 
  -         //<@@ %%z, diff %%z %%dx @@>
  -         Expr.NewTuple([z; Diff z dx ])
  -       let foldPart = MakeCall <@ foldOnRange @> [newF; newZ; st; en] [tupleTp]
  +       let foldPart = foldDiffTransform acc idx body z st en v2
          let final = MakeCall <@ snd @> [foldPart] [tp; tp]
          [ final ]
       | _ -> []
     ), "fold_d"
  +
  +let letFold_d: Rule = 
  +  (fun (e: Expr) ->
  +    match e with
  +    | DerivedPatterns.SpecificCall <@ diff @> 
  +        (_, _, [Patterns.Let(x, 
  +          DerivedPatterns.SpecificCall <@ foldOnRange @> 
  +              (_, _, [LambdaN([acc; idx], body); z; st; en]), letBody); Patterns.Var(v2)]) ->
  +       let tp = acc.Type
  +       let foldPart = foldDiffTransform acc idx body z st en v2
  +       let tupleX = new Var("tup" + x.Name, tupleType tp tp)
  +       let dx = MakeDVar(x)
  +       let diffLetBody = Diff letBody (Expr.Var(v2))
  +       let final = 
  +         LetN([tupleX, foldPart; 
  +               x, MakeCall <@ fst @> [Expr.Var(tupleX)] [tp; tp];
  +               dx, MakeCall <@ snd @> [Expr.Var(tupleX)] [tp; tp] ],
  +             diffLetBody)
  +       [ final ]
  +    | _ -> []
  +  ), "letFold_d"
   
   let build_d: Rule = 
     (fun (e: Expr) ->
  
positive.code:     | _ -> []
    ), "if_d"
  
  let lambda_d: Rule = 
    (fun (e: Expr) ->
      match e with
  
negative.code: //                       //snd (foldOnRange<Number * Number> (fun s i -> fst s, snd s) (%a, diff %a %dx) %c1 %c2)
  //                                                                                                           @>
  
  let tupleType tp1 tp2 = 
      typeof<Number * Number>.GetGenericTypeDefinition().MakeGenericType(tp1, tp2)
  
  let foldDiffTransform (acc: Var) idx body z st en v2 = 
      let tp = acc.Type
      let tupleTp = tupleType tp tp
      let newAcc = new Var(utils.newVar acc.Name, tupleTp) 
      let newAccExpr = Expr.Var(newAcc)
      //let newAccNormal = <@@ fst (%%newAccExpr) @@>
      let newAccNormal = MakeCall <@ fst @> [newAccExpr] [tp; tp]
      //let newAccDiff = <@@ snd (%%newAccExpr) @@>
      let newAccDiff = MakeCall <@ snd @> [newAccExpr] [tp; tp]
      let accd = MakeDVar(acc)
      let dx = Expr.Var(v2)
      let newBody = 
        Expr.Let(acc, newAccNormal, 
          Expr.Let(accd, newAccDiff, 
            //<@@ %%body, diff %%body %%dx @@>
            Expr.NewTuple([body; Diff body dx])
          )
        ) 
      let newF = LambdaN([newAcc; idx], newBody ) 
      let newZ = 
        //<@@ %%z, diff %%z %%dx @@>
        Expr.NewTuple([z; Diff z dx ])
      MakeCall <@ foldOnRange @> [newF; newZ; st; en] [tupleTp]
  
  let fold_d: Rule = 
    (fun (e: Expr) ->
      match e with
  