Open jamadagni opened 3 weeks ago
I agree with the baby step of simply lowering a regular function to a lambda in C++ so we can write things close to where they are used, it helps a lot with refactoring and evolving the code, something that comes up naturally while you design a solution to your problem.
Word of caution though: Supporting writing functions like this might seem controversial to others. At work, where we use Python mostly today, I have heard that inline functions (not lambda
) are the devil and should have never been supported, the perceived problem, which to be honest I have seen the worst of in a legacy project so I can understand where they come from, is that they encourage inlining all the logic within a single massive function, hurting readability, and also encourage duplication of logic (since you can't access a function within another function from anywhere else). In my experience, this is a organizational/architectural problem, more than a tooling, language or developer issue.
On the other hand, I know functional programming folks like to write functions within another function since this naturally provides encapsulation, I can appreciate that, but to be honest never thought about it too hard since C++ provides more explicit mechanisms for this, as I said before, I want to look at it from the perspective of consistency and simplicity, and disallowing writing regular functions seems like something artificial rather than a legitimate technical issue.
Finally, I have the feeling that allowing captures in regular functions should also maybe be pursued, a combination of a @pure
metafunction (or equivalent) that enforces only accessing explicitly named arguments and/or captures should help with refactoring, catching hard to track bugs in multi-threaded code, and allow to more easily reason about what you wrote.
Thanks! Very good thoughtful notes here.
Very brief ack:
auto\w*[_a-zA-Z][_a-zA-Z0-9]*\w*=\w*[
should find them?).this
) can be captured, so only local functions can do any capture by definition. (Any function, global or local, can use a global variable, but not by capturing it -- just by using its name. I would need evidence to convince me that capturing a copy of the current state of a global would make sense at any time, never mind the concurrency implications of doing that.)I would need evidence to convince me that capturing the current state of a global would many any sense at any time, never mind the concurrency implications of doing that.)
I don't really have any as there isn't much out there unfortunately 😅. Its just an itch, but it might be worth experimenting on it and see if it leads anywhere.
Background:
This request stems from #1234. I am not sure if #714 addresses this too but since @hsutter said he would like to do it, I assume this is separate and file this just to keep track of the matter.
Current situation:
Currently it is required to declare local functions (which include captures) as:
func := :() = { std::cout << "Price = " << price$ << "\n"; };
And this is rewritten into the following CPP1:
Current difficulty:
However,
:=:()=
is quite abstruse to decipher, which is why I had to ask #1234. IIANM CPP2 wants to cut out such abstruseness in the language as far as possible.So I tried to just write a local function, but:
func : () = std::cout << "Price = " << price$ << "\n";
gives:
and even without the capture:
greet : () = std::cout << "Hello\n";
gives:
Request:
I am not an expert but I am not sure there is any effective difference between a local function and a named lambda.
Given that CPP2 already rewrites code to overcome CPP1 limitations, I hence feel it should just automatically rewrite the local function as a named lambda. Hence the recommendation to “add
=
and;
” (which seems to be missing the:
) should no longer be made and CppFront should silently do this rewrite for us instead.This would also adhere to the one declaration syntax principle, rather than having the user to write
:=:()=
io the normal:()=
for effectively the same purpose.IIANM this would mean that the final
;
should also not be there, as it is there only because this is currently treated as a lambda variable definition rather than a function definition.