anchor.diff:                  | "void" -> None
                   | _ -> failwith $"Unhandled unary operator: {ue.Operator}"
   
  -            let operand = com.TransformAsExpr(ctx, ue.Argument)
  +            let operand, stmts = com.TransformAsExpr(ctx, ue.Argument)
  +
               match op with
  -            | Some op -> UnaryOp(op, operand).AsExpr()
  -            | _ -> operand
  +            | Some op -> UnaryOp(op, operand).AsExpr(), stmts
  +            | _ -> operand, stmts
   
           | :? Babel.ArrowFunctionExpression as afe ->
  -            let args = afe.Params |> List.ofArray
  -                            |> List.map (fun pattern -> Arg(Identifier pattern.Name))
  +            let args =
  +                afe.Params
  +                |> List.ofArray
  +                |> List.map (fun pattern -> Arg(Identifier pattern.Name))
  +
               let arguments = Arguments(args = args)
  -            let body = com.TransformAsStatements(ctx, (Some ReturnStrategy.ReturnUnit), afe.Body)
  -            Lambda(arguments, body).AsExpr()
  -        | :? Babel.CallExpression as ce ->  // FIXME: use transformAsCall
  -            let func = com.TransformAsExpr(ctx, ce.Callee)
  -            let args = ce.Arguments |> List.ofArray |> List.map (fun arg -> com.TransformAsExpr(ctx, arg))
  -            Call(func, args).AsExpr()
  +            match afe.Body.Body.Length with
  +            | 1 ->
  +                let body = com.TransformAsStatements(ctx, (Some ReturnStrategy.ReturnUnit), afe.Body)
  +                Lambda(arguments, body).AsExpr(), []
  +            | _ ->
  +                let body = com.TransformAsStatements(ctx, (Some ReturnStrategy.Return), afe.Body)
  +                let name = Helpers.getIdentifier("lifted")
  +                let func =
  +                    FunctionDef(
  +                        name=name,
  +                        args=arguments,
  +                        body=body
  +                    )
  +                Name(name, Load()).AsExpr(), [func]
  +        | :? Babel.CallExpression as ce -> // FIXME: use transformAsCall
  +            let func, stmts = com.TransformAsExpr(ctx, ce.Callee)
  +
  +            let args, stmtArgs =
  +                ce.Arguments
  +                |> List.ofArray
  +                |> List.map (fun arg -> com.TransformAsExpr(ctx, arg))
  +                |> Helpers.unzipArgs
  +
  +            Call(func, args).AsExpr(), stmts @ stmtArgs
           | :? Babel.ArrayExpression as ae ->
  -            let elems = ae.Elements |> List.ofArray |> List.map (fun ex -> com.TransformAsExpr(ctx, ex))
  -            Tuple(elems).AsExpr()
  -        | :? Babel.NumericLiteral as nl -> Constant(value = nl.Value).AsExpr()
  -        | :? Babel.StringLiteral as sl -> Constant(value = sl.Value).AsExpr()
  +            let elems, stmts =
  +                ae.Elements
  +                |> List.ofArray
  +                |> List.map (fun ex -> com.TransformAsExpr(ctx, ex))
  +                |> Helpers.unzipArgs
  +
  +            Tuple(elems).AsExpr(), stmts
  +        | :? Babel.NumericLiteral as nl -> Constant(value = nl.Value).AsExpr(), []
  +        | :? Babel.StringLiteral as sl -> Constant(value = sl.Value).AsExpr(), []
           | :? Babel.Identifier as ident ->
  -            let name = Helpers.cleanNameAsPythonIdentifier ident.Name
  -            Name(id = Identifier name, ctx = Load()).AsExpr()
  +            let name =
  +                Helpers.cleanNameAsPythonIdentifier ident.Name
  +
  +            Name(id = Identifier name, ctx = Load()).AsExpr(), []
           | :? Babel.NewExpression as ne -> // FIXME: use transformAsCall
  -            let func = com.TransformAsExpr(ctx, ne.Callee)
  -            let args = ne.Arguments |> List.ofArray |> List.map (fun arg -> com.TransformAsExpr(ctx, arg))
  -            Call(func, args).AsExpr()
  +            let func, stmts = com.TransformAsExpr(ctx, ne.Callee)
  +
  +            let args, stmtArgs =
  +                ne.Arguments
  +                |> List.ofArray
  +                |> List.map (fun arg -> com.TransformAsExpr(ctx, arg))
  +                |> Helpers.unzipArgs
  +
  +            Call(func, args).AsExpr(), stmts @ stmtArgs
           | :? Babel.Super ->
  -            Name(Identifier("super().__init__"), ctx = Load()).AsExpr()
  +            Name(Identifier("super().__init__"), ctx = Load())
  +                .AsExpr(),
  +            []
           | :? Babel.ObjectExpression as oe ->
  -             let kv = [
  -                 for prop in oe.Properties do
  +            let kv =
  +                [ for prop in oe.Properties do
                       match prop with
                       | :? Babel.ObjectProperty as op ->
  -                        let key = com.TransformAsExpr(ctx, op.Key)
  -                        let value = com.TransformAsExpr(ctx, op.Value)
  +                        let key, _ = com.TransformAsExpr(ctx, op.Key)
  +                        let value, _ = com.TransformAsExpr(ctx, op.Value)
                           key, value
  -                     | _ -> failwith $"transformAsExpr: unhandled object expression property: {prop}"
  -             ]
  -             let keys = kv |> List.map fst
  -             let values = kv |> List.map snd
  -             Dict(keys=keys, values=values).AsExpr()
  -        | :? Babel.EmitExpression as ee ->
  -            failwith "Not Implemented"
  +                    | _ -> failwith $"transformAsExpr: unhandled object expression property: {prop}" ]
  +
  +            let keys = kv |> List.map fst
  +            let values = kv |> List.map snd
  +            Dict(keys = keys, values = values).AsExpr(), []
  +        | :? Babel.EmitExpression as ee -> failwith "Not Implemented"
           | :? Babel.MemberExpression as me ->
  -            let value = com.TransformAsExpr(ctx, me.Object)
  +            let value, stmts = com.TransformAsExpr(ctx, me.Object)
  +
               if me.Computed then
                   let attr =
                       match me.Property with
                       | :? Babel.NumericLiteral as nl -> Constant(nl.Value)
                       | _ -> failwith $"transformExpressionAsStatements: unknown property {me.Property}"
  -                Subscript(value=value, slice=attr, ctx=Load()).AsExpr()
  +
  +                Subscript(value = value, slice = attr, ctx = Load())
  +                    .AsExpr(),
  +                stmts
               else
                   let attr =
                       match me.Property with
                       | :? Babel.Identifier as id -> Identifier(id.Name)
                       | _ -> failwith $"transformExpressionAsStatements: unknown property {me.Property}"
  -                Attribute(value=value, attr=attr, ctx=Load()).AsExpr()
  -        | :? Babel.BooleanLiteral as bl ->
  -            Constant(value=bl.Value).AsExpr()
  +
  +                Attribute(value = value, attr = attr, ctx = Load())
  +                    .AsExpr(),
  +                stmts
  +        | :? Babel.BooleanLiteral as bl -> Constant(value = bl.Value).AsExpr(), []
  +        | :? Babel.FunctionExpression as fe ->
  +            let args =
  +                fe.Params
  +                |> List.ofArray
  +                |> List.map (fun pattern -> Arg(Identifier pattern.Name))
  +
  +            let arguments = Arguments(args = args)
  +            match fe.Body.Body.Length with
  +            | 1 ->
  +                let body = com.TransformAsStatements(ctx, (Some ReturnStrategy.ReturnUnit), fe.Body)
  +                Lambda(arguments, body).AsExpr(), []
  +            | _ ->
  +                let body = com.TransformAsStatements(ctx, (Some ReturnStrategy.Return), fe.Body)
  +                let name = Helpers.getIdentifier("lifted")
  +                let func =
  +                    FunctionDef(
  +                        name=name,
  +                        args=arguments,
  +                        body=body
  +                    )
  +                Name(name, Load()).AsExpr(), [func]
           | _ -> failwith $"Unhandled value: {expr}"
   
       /// Transform Babel expressions as Python statements.
  -    let rec transformExpressionAsStatements (com: IPythonCompiler) ctx (returnStrategy: ReturnStrategy option) (expr: Babel.Expression): Statement list =
  +    let rec transformExpressionAsStatements
  +        (com: IPythonCompiler)
  +        (ctx: Context)
  +        (returnStrategy: ReturnStrategy option)
  +        (expr: Babel.Expression)
  +        : Statement list =
           printfn $"transformExpressionAsStatements: {expr}"
   
           match expr with
           | :? Babel.AssignmentExpression as ae ->
  -            let value = com.TransformAsExpr(ctx, ae.Right)
  +            let value, stmts = com.TransformAsExpr(ctx, ae.Right)
  +
               let targets: Expression list =
                   let attr =
                       match ae.Left with
  
positive.code:                     match decl.Declaration with
                      | :? Babel.VariableDeclaration as decl ->
                          for decls in decl.Declarations do
                              let value = com.TransformAsExpr(ctx, decls.Init.Value)
                              let targets: Expression list =
                                  [ Name(id = Identifier(decls.Id.Name), ctx = Store()) ]
  
                              yield Assign(targets = targets, value = value)
                      | :? Babel.FunctionDeclaration as fd ->
                          let args =
  
negative.code:     inherit Compiler
      //abstract GetAllImports: unit -> seq<Python.Import>
      //abstract GetImportExpr: Context * selector: string * path: string * SourceLocation option -> Expression
      abstract TransformAsExpr: Context * Babel.Expression -> Expression * Statement list
      abstract TransformAsStatements: Context * ReturnStrategy option * Babel.Statement -> Statement list
      abstract TransformAsStatements: Context * ReturnStrategy option * Babel.Expression -> Statement list
      abstract TransformAsClassDef: Context * Babel.ClassDeclaration -> Statement
  