How to Immediately Invoke a C++ Lambda

Execute lambda expression immediately after its definition?

Sure.

new Action(() => { Console.WriteLine("Hello World"); })();

That should do the trick.

How to immediately invoke a C++ lambda?

But now that has me thinking -- did I do this correctly?

Yes you did.

Is there a better way in C++11 or C++14 to tell the compiler that I want it to immediately invoke a lambda I've written?

Not that I know of. A lambda is also just a function object, so you need to have a () to call it, there is no way around it (except of course some function that invokes the lambda like std::invoke).

If you want you can drop the () after the capture list, because your lambda doesn't take any parameters.

Or is appending an empty () like I did the usual way to do this?

Yes, it is the shortest way. As said before, std::invoke would also work instead, but it requires more typing. I would say a direct call with () is the usual way it is done.

Is there a way to declare a C# lambda and immediately call it?

Instead of trying to cast the lambda, I propose you use a small helper function:

public static TOut Exec<TIn, TOut>(Func<TIn, TOut> func, TIn input) => func(input);

which you could then use like this: int x = Exec(myVar => myVar + 2, 0);. This reads a lot nicer to me than the alternatives suggested here.

Define a lambda function and execute it immediately

A lambda just does not support being executed. A delegate supports being executed. A lambda expression can be implicitly converted to a delegate type. In case no such conversion is requested there is no "default" delegate type. Since .NET 2 we normally use Action and Func for everything but we could use different delegate types.

First convert to a delegate, then execute:

((Func<int>)(() => 0))()

One could argue that C# should default to using Action and Func if nothing else was requested. The language does not do that as of C# 5.

How can I run a lambda immediately?

You can invoke the lambda immediately by placing parenthesis at the end like shown below:

int x = 0;
[&]{ std::cout << ++x << '\n'; }();
// ^^

Now this will print out 1

Is there an Immediately Invoked Anonymous Function for Java?

No because lambdas need a target type. The best you can do is cast the expression:

Item similarItem = ((Supplier<Item>) (() -> {
for (Item i : POSSIBLE_ITEMS) {
if (i.name.equals(this.name)) return i;
}
return null;
})).get();

You must use the correct Functional Interface for your particular lambda. As you can see, it is very clunky and not useful.


UPDATE

The above code is a direct translation of the JavaScript code. However, converting code directly will not always give the best result.

In Java you'd actually use streams to do what that code is doing:

Item similarItem = POSSIBLE_ITEMS.stream()
.filter(i -> i.name.equals(this.name))
.findFirst()
.orElse(null);

The above code assumes that POSSIBLE_ITEMS is a Collection, likely a List. If it is an array, use this instead:

Item similarItem = Arrays.stream(POSSIBLE_ITEMS)
.filter(i -> i.name.equals(this.name))
.findFirst()
.orElse(null);

Can a lambda expression be declared and invoked at the same time in C#?

You have to tell the compiler a specific delegate type. For example, you could cast the lambda expression:

Console.WriteLine(((Func<int, int>)(x => x + 1))(2));

EDIT: Or yes, you can use a delegate creation expression as per Servy's answer:

Console.WriteLine(new Func<int, int>(i => i + 1)(2));

Note that this isn't really a normal constructor call - it's special syntax for delegate creation which looks like a regular constructor call. Still clever though :)

You can make it slightly cleaner with a helper class:

public static class Functions
{
public static Func<T> Of<T>(Func<T> input)
{
return input;
}

public static Func<T1, TResult> Of<T1, TResult>
(Func<T1, TResult> input)
{
return input;
}

public static Func<T1, T2, TResult> Of<T1, T2, TResult>
(Func<T1, T2, TResult> input)
{
return input;
}
}

... then:

Console.WriteLine(Functions.Of<int, int>(x => x + 1)(2));

Or:

Console.WriteLine(Functions.Of((int x) => x + 1)(2));

Are there any official ways to write an Immediately Invoked Function Expression?

I'm surprised no one's mentioned this yet, but you could use the Lazy<T> class:

var myObject = new MyClass()
{
x = new Lazy<string>(() =>
{
//Do stuff..
if (2 + 2 == 5)
return "I like cookies";
else if (2 + 2 == 3)
return "I like muffins";
//More conditions...
else
return "I'm a bitter old man";
}).Value // <-- Evaluate the function here
};

Alternatively, if you want to avoid having to specify the return type anywhere (as you do with new Lazy<string> because constructors do not support type inference), you can implement a simple generic method like this:

public static T Eval<T>(Func<T> func)
{
return func();
}

And then you can call like this:

var myObject = new MyClass()
{
x = Eval(() =>
{
//Do stuff..
if (2 + 2 == 5)
return "I like cookies";
else if (2 + 2 == 3)
return "I like muffins";
//More conditions...
else
return "I'm a bitter old man";
})
};

Update: C#7 introduces local functions. These are not really IFFEs, but they may solve a variety of related issues. For example:

var myObject = new MyClass()
{
x = GetX()
};

string GetX() {
//Do stuff..
if (2 + 2 == 5)
return "I like cookies";
else if (2 + 2 == 3)
return "I like muffins";
//More conditions...
else
return "I'm a bitter old man";
}

The key here is that GetX can be declared within the same method as myObject share the same scope as it.

Usage of lambda in constant expression

[gcc] was getting hung up on the try, that normally wouldn't be allowed in a constexpr function.

This is correct for a C++17 program. (C++20 relaxed this, so a try block can now be used in a constexpr function. However, it is only the try that is allowed; it is not allowed for execution to hit something that throws an exception.)

That's why I had to use an immediately invoked lambda expression.

The implication here is that your approach made your code valid. This is incorrect. Using an an immediately invoked lambda did not work around the problem; it swept the problem under the rug. The try is still a problem, but now compilers do not have to tell you it is a problem.

Using a lambda switches the constexpr criterion from the straight-forward "the function body must not contain a try-block" to the indirect "there exists at least one set of argument values such that an invocation of the function could be an evaluated subexpression of a core constant expression". The tricky part here is that a violation of the latter criterion is "no diagnostic required", meaning that all the compilers are correct, whether or not they complain about this code. Hence my characterization of this as sweeping the problem under the rug.

So why is... that criterion is a long thing to repeat... what's the issue involving "core constant expressions"? C++17 removed the prohibition against lambdas in core constant expressions, so that much looks good. However, there is still a requirement that all function calls within the constexpr function also be themselves constexpr. Lambdas can become constexpr in two ways. First, they can be explicitly marked constexpr (but if you do that here, the complaint about the try block should come back). Second, they can simply satisfy the constexpr function requirements. However, your lambda contains a try, so it is not constexpr (in C++17).

Your lambda is not a valid constexpr function. Hence calling it is not allowed in a core constant expression. There is no execution path through can_represent() that avoids invoking your lambda. Therefore, can_represent is not a valid constexpr function, no diagnostic required.

Invoke a lambda without creating a delegate; causes CS0149 Method name expected

The concept of a lambda expression only exists as source code. It doesn't even have a type in itself (just like the null literal doesn't have a type). It has to be converted to either an expression tree or a delegate: that's what exists as far as the IL and the CLR are concerned. The compiler has to emit code to create something, and you need to tell it which type you want that to be.

The compiler doesn't play favourites in terms of delegate types: while it could "know" about Func<T> and use that as a default delegate type for a lambda expression with no parameters, it doesn't.

The closest you'll get to what you want is to have a convenience method that you can call accepting a Func<T>, which could either just return the function, or execute it and return the result. For example:

public static Func<T> CreateFunc<T>(Func<T> func) => func;
public static T ExecuteFunc<T>(Func<T> func) => func();

Then you can call it as:

CreateFunc(() => 42)();

or

ExecuteFunc(() => 42);


Related Topics



Leave a reply



Submit