The background of this story is pretty long, so to keep things short -- I know goto is bad, but I have no other choice, because... PHP lacks comma operator.
I have such pattern -- regular function with entry point given as label, and inside it a small lambda which needs to goto
to that entry point. Something like this (incorrect code):
function water()
{
_Entry_point_2_0:
// ... some code
(function() { /*...*/ ;goto _Entry_point_2_0;})();
// ... some code
}
I cannot just jump across the function boundaries, so my next idea is to return the label from the lambda and use it as "value" for goto. Something like this:
function water()
{
_Entry_point_2_0:
// ... some code
goto (function() { /*...*/ ;return '_Entry_point_2_0';})();
// ... some code
}
This does not work. Evaluating entire goto
as a string eval ('goto _Entry_point_2_0;')
does not work either.
The crazy part is I know the label in advance, so you can ask why I cannot write entire function like that:
function water()
{
_Entry_point_2_0:
// ... some code
(function() { /*...*/ ;})();
goto _Entry_point_2_0;
// ... some code
}
The problem is in logic -- executing lambda and goto make 2 expressions now, not one. And I need to make it in one expression -- execute lambda and goto has to be packed in single expression.
I also cannot call recursively the main function because it is whole point of this work, to avoid recursive call :-).
What are the other ways to achieve this?
UPDATE 1 Maybe I rephrase -- what I would like to achieve with goto is continue my_function
. Executed from or at the boundary of the inner function (i.e. lambda).
UPDATE 2 The main goal is to loop over the main function, so it is almost equivalent to:
function water()
{
_Entry_point_2_0: while (true)
{
// ... some code
continue (function() { /*...*/ ; return '_Entry_point_2_0'; })();
// ... some code
}
}
"Almost" because of two reasons. I still have the problem with labels exactly as before, and what's more now I have problem where to add break
s to the loop.
Perhaps you are trying to solving your attemted solution rather than your original problem. This question smells XY problem.
_Entry_point_2_0:
// ... some code
(function() { /*...*/ ;goto _Entry_point_2_0;})();
Looks for me like do while
loop:
do {
// ... some code
} while ((function() { /*...*/ ; return $k !== 0;})());
Now applying an anonymous function like that is not allowed. In addition closure parameters need to be explicitly declared. Thus my solution needs to be written like this:
$k = 10;
$f = function() use (&$k) { /*...*/ ; return $k !== 0; };
do {
// some code
} while ( $f() );
If you want to have a "comma operator" you just make a function that takes any numbers of argumens and return the last:
function begin(){
return func_get_args()[func_num_args()-1];
}
begin(expression1, expression2, expression3); // ==> result of expression3
All of a function arguments gets evaluated so it does the same given that the arguments are not dependent on each other.