anchor.diff:          | (Patterns.Value _) as value -> optimize <| constantReplacement var value body
           | optimizedBinding -> Expr.Let (var, optimizedBinding, optimize body)
       | Patterns.Application (Lambda(var, body), input) -> optimize <| Expr.Let (var, input, body)
  -    | Λ ``|>`` (None, _, [x1;x2]) -> optimize <| Expr.Application (x2, x1)
  -    | Λ ``<|`` (None, _, [x1;x2]) -> optimize <| Expr.Application (x1, x2)
  -    | Λ ``+`` (None, [|t1;_;_|], [x1;x2]) when t1 = typeof<string> ->
  +    | Λ ``-> |>`` (None, _, [x1;x2]) -> optimize <| Expr.Application (x2, x1)
  +    | Λ ``-> <|`` (None, _, [x1;x2]) -> optimize <| Expr.Application (x1, x2)
  +    | Λ ``-> +`` (None, [|t1;_;_|], [x1;x2]) when t1 = typeof<string> ->
           let rec getStrings strings = function
  -        | Λ ``+`` (None, [|t1;_;_|], [x1;x2]) when t1 = typeof<string> -> getStrings (x2::strings) (x1)
  +        | Λ ``-> +`` (None, [|t1;_;_|], [x1;x2]) when t1 = typeof<string> -> getStrings (x2::strings) (x1)
           | remainder -> remainder :: strings
           let concat = 
               match getStrings [x2] (x1) with
  
positive.code:         else
              e
  
      let (|NotQ|_|) =  (|SpecificCall|_|) <@ not   @>
      let (|NegQ|_|) = (|SpecificCall|_|) <@ ( ~-) : int -> int @>
      let (|PlusQ|_|)      = (|SpecificCall|_|) <@ ( + ) @>
      let (|DivideQ|_|) = (|SpecificCall|_|) <@ ( / ) @> 
      let (|MinusQ|_|) = (|SpecificCall|_|) <@ ( - ) @>
      let (|MultiplyQ|_|) = (|SpecificCall|_|) <@ ( * ) @>
      let (|ModuloQ|_|) = (|SpecificCall|_|) <@ ( % ) @>
      let (|ShiftLeftQ|_|) = (|SpecificCall|_|) <@ ( <<< ) @>
      let (|ShiftRightQ|_|) = (|SpecificCall|_|) <@ ( >>> ) @>
      let (|BitwiseAndQ|_|) = (|SpecificCall|_|) <@ ( &&& ) @>
      let (|BitwiseOrQ|_|) = (|SpecificCall|_|) <@ ( ||| ) @>
      let (|BitwiseXorQ|_|) = (|SpecificCall|_|) <@ ( ^^^ ) @>
      let (|BitwiseNotQ|_|) = (|SpecificCall|_|) <@ ( ~~~ ) @>
      let (|CheckedNeg|_|) = (|SpecificCall|_|) <@ Checked.( ~-) : int -> int @>
      let (|CheckedPlusQ|_|)      = (|SpecificCall|_|) <@ Checked.( + ) @>
      let (|CheckedMinusQ|_|) = (|SpecificCall|_|) <@ Checked.( - ) @>
      let (|CheckedMultiplyQ|_|) = (|SpecificCall|_|) <@ Checked.( * ) @>
      let (|ConvCharQ|_|) = (|SpecificCall|_|) <@ char @>
      let (|ConvDecimalQ|_|) = (|SpecificCall|_|) <@ decimal @>
      let (|ConvFloatQ|_|) = (|SpecificCall|_|) <@ float @>
      let (|ConvFloat32Q|_|) = (|SpecificCall|_|) <@ float32 @>
      let (|ConvSByteQ|_|) = (|SpecificCall|_|) <@ sbyte @>
      let (|ConvInt16Q|_|) = (|SpecificCall|_|) <@ int16 @>
      let (|ConvInt32Q|_|) = (|SpecificCall|_|) <@ int32 @>
      let (|ConvIntQ|_|) = (|SpecificCall|_|) <@ int @>
      let (|ConvInt64Q|_|) = (|SpecificCall|_|) <@ int64 @>
      let (|ConvByteQ|_|) = (|SpecificCall|_|) <@ byte @>
      let (|ConvUInt16Q|_|) = (|SpecificCall|_|) <@ uint16 @>
      let (|ConvUInt32Q|_|) = (|SpecificCall|_|) <@ uint32 @>
      let (|ConvUInt64Q|_|) = (|SpecificCall|_|) <@ uint64 @>
  
      let (|CheckedConvCharQ|_|) = (|SpecificCall|_|) <@ Checked.char @>
      let (|CheckedConvSByteQ|_|) = (|SpecificCall|_|) <@ Checked.sbyte @>
      let (|CheckedConvInt16Q|_|) = (|SpecificCall|_|) <@ Checked.int16 @>
      let (|CheckedConvInt32Q|_|) = (|SpecificCall|_|) <@ Checked.int32 @>
      let (|CheckedConvInt64Q|_|) = (|SpecificCall|_|) <@ Checked.int64 @>
      let (|CheckedConvByteQ|_|) = (|SpecificCall|_|) <@ Checked.byte @>
      let (|CheckedConvUInt16Q|_|) = (|SpecificCall|_|) <@ Checked.uint16 @>
      let (|CheckedConvUInt32Q|_|) = (|SpecificCall|_|) <@ Checked.uint32 @>
      let (|CheckedConvUInt64Q|_|) = (|SpecificCall|_|) <@ Checked.uint64 @>
      let (|LinqExpressionHelperQ|_|) = (|SpecificCall|_|) <@ LinqExpressionHelper @>
      let (|ArrayLookupQ|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.GetArray : int[] -> int -> int @>
      let (|ArrayAssignQ|_|) = (|SpecificCall|_|) <@ LanguagePrimitives.IntrinsicFunctions.SetArray : int[] -> int -> int -> unit @>
      let (|ArrayTypeQ|_|) (ty:System.Type) = if ty.IsArray && ty.GetArrayRank() = 1 then Some(ty.GetElementType()) else None
      
      /// Convert F# quotations to LINQ expression trees.
  
negative.code:                     exprConstructor(e1, e2, false, intrinsic.MakeGenericMethod([|x1.Type|])) |> asExpr
  
              match inp with 
  //            | SpecificCall <@ ( .. ) @> (_,_,[x1;x2]) -> transComparison x1 x2 Expression.Equal              Expression.Equal              genericEqualityIntrinsic
  
              | Λ ``-> generic=`` (_,_,[x1;x2])
              | Λ ``-> =``  (_,_,[x1;x2]) -> transComparison x1 x2 Expression.Equal              Expression.Equal              genericEqualityIntrinsic
              | Λ ``-> >``  (_,_,[x1;x2]) -> transComparison x1 x2 Expression.GreaterThan        Expression.GreaterThan        genericGreaterThanIntrinsic
              | Λ ``-> >=`` (_,_,[x1;x2]) -> transComparison x1 x2 Expression.GreaterThanOrEqual Expression.GreaterThanOrEqual genericGreaterOrEqualIntrinsic
              | Λ ``-> <``  (_,_,[x1;x2]) -> transComparison x1 x2 Expression.LessThan           Expression.LessThan           genericLessThanIntrinsic
              | Λ ``-> <=`` (_,_,[x1;x2]) -> transComparison x1 x2 Expression.LessThanOrEqual    Expression.LessThanOrEqual    genericLessOrEqualIntrinsic
              | Λ ``-> <>`` (_,_,[x1;x2]) -> transComparison x1 x2 Expression.NotEqual           Expression.NotEqual           genericNotEqualIntrinsic
  
              | Λ ``-> not`` (_,_,[x1])    -> Expression.Not(ConvExpr env x1)                                   |> asExpr
              | Λ ``-> ~-``  (_,_,[x1])    -> Expression.Negate(ConvExpr env x1)                                |> asExpr
              | Λ ``-> +``   (_,_,[x1;x2]) -> Expression.Add(ConvExpr env x1, ConvExpr env x2)      |> asExpr
              | Λ ``-> /``   (_,_,[x1;x2]) -> Expression.Divide (ConvExpr env x1, ConvExpr env x2)  |> asExpr
              | Λ ``-> -``   (_,_,[x1;x2]) -> Expression.Subtract(ConvExpr env x1, ConvExpr env x2) |> asExpr
              | Λ ``-> *``   (_,_,[x1;x2]) -> Expression.Multiply(ConvExpr env x1, ConvExpr env x2) |> asExpr
              | Λ ``-> %``   (_,_,[x1;x2]) -> Expression.Modulo (ConvExpr env x1, ConvExpr env x2) |> asExpr
                   /// REVIEW: basic arithmetic with method witnesses
                   /// REVIEW: negate,add, divide, multiply, subtract with method witness
  
              | Λ ``-> <<<`` (_,_,[x1;x2]) -> Expression.LeftShift(ConvExpr env x1, ConvExpr env x2) |> asExpr
              | Λ ``-> >>>`` (_,_,[x1;x2]) -> Expression.RightShift(ConvExpr env x1, ConvExpr env x2) |> asExpr
              | Λ ``-> &&&`` (_,_,[x1;x2]) -> Expression.And(ConvExpr env x1, ConvExpr env x2) |> asExpr
              | Λ ``-> |||`` (_,_,[x1;x2]) -> Expression.Or(ConvExpr env x1, ConvExpr env x2) |> asExpr
              | Λ ``-> ^^^`` (_,_,[x1;x2]) -> Expression.ExclusiveOr(ConvExpr env x1, ConvExpr env x2) |> asExpr
              | Λ ``-> ~~~`` (_,_,[x1]) -> Expression.Not(ConvExpr env x1) |> asExpr
                   /// REVIEW: bitwise operations with method witnesses
  
              | Λ ``-> checked~-`` (_, _,[x1]) -> Expression.NegateChecked(ConvExpr env x1)                                |> asExpr
              | Λ ``-> checked+`` (_, _,[x1;x2]) -> Expression.AddChecked(ConvExpr env x1, ConvExpr env x2)      |> asExpr
              | Λ ``-> checked-`` (_, _,[x1;x2]) -> Expression.SubtractChecked(ConvExpr env x1, ConvExpr env x2) |> asExpr
              | Λ ``-> checked*`` (_, _,[x1;x2]) -> Expression.MultiplyChecked(ConvExpr env x1, ConvExpr env x2) |> asExpr
  
              | Λ ``-> char``    (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<char>) |> asExpr
              | Λ ``-> decimal`` (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<decimal>) |> asExpr
              | Λ ``-> float``   (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<float>) |> asExpr
              | Λ ``-> float32`` (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<float32>) |> asExpr
              | Λ ``-> sbyte``   (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<sbyte>) |> asExpr
              | Λ ``-> int16``   (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<int16>) |> asExpr
              | Λ ``-> int32``   (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<int32>) |> asExpr
              | Λ ``-> int``     (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<int32>) |> asExpr
              | Λ ``-> int64``   (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<int64>) |> asExpr
              | Λ ``-> byte``    (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<byte>) |> asExpr
              | Λ ``-> uint16``  (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<uint16>) |> asExpr
              | Λ ``-> uint32``  (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<uint32>) |> asExpr
              | Λ ``-> uint64``  (_, [|ty|],[x1]) -> Expression.Convert(ConvExpr env x1, typeof<uint64>) |> asExpr
               /// REVIEW: convert with method witness
  
              | Λ ``-> checked.char``   (_, [|ty|],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<char>) |> asExpr
              | Λ ``-> checked.sbyte``  (_, [|ty|],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<sbyte>) |> asExpr
              | Λ ``-> checked.int16``  (_, [|ty|],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<int16>) |> asExpr
              | Λ ``-> checked.int32``  (_, [|ty|],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<int32>) |> asExpr
              | Λ ``-> checked.int64``  (_, [|ty|],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<int64>) |> asExpr
              | Λ ``-> checked.byte``   (_, [|ty|],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<byte>) |> asExpr
              | Λ ``-> checked.uint16`` (_, [|ty|],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<uint16>) |> asExpr
              | Λ ``-> checked.uint32`` (_, [|ty|],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<uint32>) |> asExpr
              | Λ ``-> checked.uint64`` (_, [|ty|],[x1]) -> Expression.ConvertChecked(ConvExpr env x1, typeof<uint64>) |> asExpr
  
              | Λ ``-> getArray``  (_, [|ArrayTypeQ(elemTy);_;_|],[x1;x2]) -> 
                  Expression.ArrayIndex(ConvExpr env x1, ConvExpr env x2) |> asExpr
  
              | Λ ``-> setArray``  (_, [|ArrayTypeQ(elemTy);_;_|],[arr;idx;elem]) -> 
                  let minfo = ArrayAssignMethod.GetGenericMethodDefinition().MakeGenericMethod [| elemTy;typeof<unit> |]
                  Expression.Call(minfo,[| ConvExpr env arr; ConvExpr env idx; ConvExpr env elem |]) |> asExpr
              
              // Throw away markers inserted to satisfy C#'s design where they pass an argument
              // or type T to an argument expecting Expr<T>.
              | Λ ``-> linqExpressionHelper`` (_, [|_|],[x1]) -> ConvExpr env x1
               
                /// ArrayLength
                /// ListBind
  