Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6967831
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T16:22:24+00:00 2026-05-27T16:22:24+00:00

I try to build a tail recursive Expression in .NET 4.0. I can build

  • 0

I try to build a tail recursive Expression in .NET 4.0.

I can build it but, this the compiled method isn’t tail-call optimized, despite specifing tailCall = true, the generated IL doesn’t have a tail. prefix instruction.

Please tell me how to build a tail-call optimized recursive Expression?

Build expression is below.

using System;
using System.Linq.Expressions;

namespace ConsoleApplication2
{
    public delegate int RecursiveFunc(RecursiveFunc function, int acc, int n);

    internal class Program
    {
        private static void Main()
        {
            var funcParam = Expression.Parameter(typeof (RecursiveFunc));
            var accParam = Expression.Parameter(typeof (int));
            var nParam = Expression.Parameter(typeof (int));
            var constZero = Expression.Constant(0, typeof (int));

            var accumExpr = Expression.Add(accParam, nParam);
            var decrimentExpr = Expression.Decrement(nParam);

            var invokeExpr = Expression.Invoke(funcParam, funcParam, 
                accumExpr, decrimentExpr);

            var testExpr = Expression.Equal(nParam, constZero);
            var condExpr = Expression.Condition(testExpr, accParam, 
                invokeExpr);

            var lambda = Expression.Lambda<RecursiveFunc>(condExpr, 
                "TailCall", true, new[] {funcParam, accParam, nParam});

            var sumParam = Expression.Parameter(typeof (RecursiveFunc), 
                "Sum");

            var method = lambda.Compile();

            var ans = method(method, 0, 100);
            Console.WriteLine(ans);
        }
    }
}

And this lambda expresion generated IL is below

.method public static int32 EvaluateTarget (
    class [ConsoleApplication2]ConsoleApplication2.RecursiveFunc '',
    int32 '',
    int32 ''
) cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 25 (0x19)
    .maxstack 7

    IL_0000: ldarg.2
    IL_0001: ldc.i4.0
    IL_0002: ceq
    IL_0004: brfalse IL_000b

    IL_0009: ldarg.1
    IL_000a: ret

    IL_000b: ldarg.0
    IL_000c: ldarg.0
    IL_000d: ldarg.1
    IL_000e: ldarg.2
    IL_000f: add
    IL_0010: ldarg.2
    IL_0011: ldc.i4.1
    IL_0012: sub
    IL_0013: callvirt instance int32   
        [ConsoleApplication2]ConsoleApplication2.RecursiveFunc::Invoke(class 
        [ConsoleApplication2]ConsoleApplication2.RecursiveFunc, int32, int32)
    IL_0018: ret
} // end of method AutoGeneratedType::EvaluateTarget
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T16:22:25+00:00Added an answer on May 27, 2026 at 4:22 pm

    The following works around:

    using System;
    using System.Linq.Expressions;
    using System.Reflection.Emit;
    
    namespace ConsoleApplication2
    {
        public delegate int RecursiveFunc(RecursiveFunc doCall, RecursiveFunc function, int acc, int n);
    
        internal class Program
        {
            private static void Main()
            {
                DynamicMethod dm = new DynamicMethod("DoInvokeWithTailCall", typeof(int), new Type[] { typeof(RecursiveFunc), typeof(RecursiveFunc), typeof(int), typeof(int) }, typeof(Program).Module);
                ILGenerator il = dm.GetILGenerator();
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldarg_3);
                il.Emit(OpCodes.Tailcall);
                il.EmitCall(OpCodes.Callvirt, typeof(RecursiveFunc).GetMethod("Invoke"), null);
                il.Emit(OpCodes.Ret);
                RecursiveFunc doCall = (RecursiveFunc)dm.CreateDelegate(typeof(RecursiveFunc));
    
                var doCallParam = Expression.Parameter(typeof(RecursiveFunc));
                var funcParam = Expression.Parameter(typeof(RecursiveFunc));
                var accParam = Expression.Parameter(typeof(int));
                var nParam = Expression.Parameter(typeof(int));
                var constZero = Expression.Constant(0, typeof(int));
    
                var accumExpr = Expression.Add(accParam, nParam);
                var decrimentExpr = Expression.Decrement(nParam);
    
                //var invokeExpr = Expression.Invoke(funcParam, funcParam, funcParam, accumExpr, decrimentExpr); 
                var invokeExpr = Expression.Call(dm, doCallParam, funcParam, accumExpr, decrimentExpr);
    
                var testExpr = Expression.Equal(nParam, constZero);
                var condExpr = Expression.Condition(testExpr, accParam,
                    invokeExpr);
    
                var lambda = Expression.Lambda<RecursiveFunc>(condExpr,
                    "TailCall", true, new[] { doCallParam, funcParam, accParam, nParam });
    
                var method = lambda.Compile();
    
                var ans = method(doCall, method, 0, 100);
                Console.WriteLine(ans);
            }
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I try to build extension method for IQuerable like this: public static IQueryable<T> FilterByString<T>(this
I am getting this error when I try to build for the device: Code
I've included: #import QuartzCore/QuartzCore.h but when I try to build, I get the error
I try to build an application on Android. And I'm new in Android. But
I try to build a product with Tycho 0.13.0, but I get a following
I get the following errors when I try to build this project: error C2182:
Please i have this error when i try to build my project : duplicate
I try to build subproject ExplorerPlugin from mDNSResponder-107.6.tar.gz archive but receive next link error:
Whenever I try to build an application with Interix's GCC on Windows, this is
i try to build up the scrollView which can scroll certain amount of distance

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.