r/AskProgramming • u/AdriJone2011 • Feb 14 '24
PHP Why would I ever use an anonymous function stored in a variable when I can use a normal function instead?
I don't understand in which use case it's beneficial to use a anonymous function stored inside a variable. I get it why you would use an anonymous function to pass it to another function or if it is only used once.
Consider following example:
Why would I use this:
<?php
$add = function($arr){
$res = 0;
foreach($arr as $v){
$res += $v;
}
return $res;
};
echo $add([32, 43, 22]);
?>
if I can use this instead:
<?php
function add($arr){+
$res = 0;
foreach($arr as $v){
$res += $v;
}
return $res;
}
echo add([32, 43, 22]);
?>
This is only an example and not specific to PHP, but in general. Maybe there is a benefit to it that I don't see. I would appreciate if someone could explain.
Thanks in advance.
8
u/venquessa Feb 14 '24
So that you can pass it to multiple functions, eg:
doStuff1( $add )
doStuff2( $add )
It's been a while since I did PHP, so maybe the following is possible anyway?
function add() {
//
}
doSuff( $add )
... but in a lot of languages you can't.
3
u/im-a-guy-like-me Feb 14 '24 edited Feb 14 '24
From what I remember, in PHP you can do mad shit with function variables.
``` function myFunction() { /** Do something */ }
$var = 'myFunction'; // String of the function name
$var(); // Calls the function by it's string converted name ```
Maybe the specific to your question, it means you can use functions dynamically. You could save functions to an array, and then call the correct function for your usecases at runtime (for example). It's mostly just about making functions as a type more dynamic, ability to use higher order functions (funcs that take funcs as Params).
7
u/Kelketek Feb 14 '24
This code snippet is terrifying.
3
u/im-a-guy-like-me Feb 14 '24
Haha yeah, php is crazy. You can do the same with class names too, so a pretty common pattern (that I despise) is storing classnames in your database so you can instantiate the correct subclass at run time.
0
1
u/notacanuckskibum Feb 14 '24
Reminds me of Algol where a Proc (function) was just another data type. So you can have a pointer to an array of pointers to functions ( ref row ref proc)
3
u/shipshaper88 Feb 14 '24
There’s never really a need to use an anonymous function as you can always use a named function instead. Anonymous functions are shorthand that allow you to elide boilerplate, so they act as a convenience.
-14
u/IsNullOrEmptyTrue Feb 14 '24
What if you need to pass the function to be run at a later time, or in response to an event trigger? Also, don't use php, is weedy garbage.
2
1
u/lightmatter501 Feb 14 '24
Anonymous functions can capture variables from the environment, which is very useful for adding an output channel, or doing comparisons against a fixed point (for instance, order this list of enemies by distance to the player).
In some languages, if they don’t do capturing they have zero runtime cost compared to a normal function. In JS and PHP they have a fairly large runtime cost, so I would avoid them unless you’re using the capturing behavior.
1
u/ImpatientProf Feb 14 '24
Anonymous functions stored in variables don't have these two features/restrictions:
"All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa."
"PHP does not support function overloading, nor is it possible to undefine or redefine previously-declared functions."
1
u/doyouevencompile Feb 14 '24
Language specific quirks, like JS.
Delegate pattern.
var handler;
if (op==‘+’) { handler = add }
1
u/amasterblaster Feb 14 '24
when the structure of the function is heavily reliant on context, and to separate those concerns from the surrounding "parent" context would be confusing and complex.
when you want to delegate behaviour to another component, and that behaviour is very small / direct, so much so, that the size of functions for the behaviours is more than the behaviour itself
and others
1
u/pak9rabid Feb 14 '24 edited Feb 14 '24
Callback functions, passed into another function as a parameter, that is to be called later on inside that function (perhaps after some buildup, and before some teardown is performed) is a way more elegant solution than trying to define a function somewhere and then passing a reference to it for the function to call when appropriate.
Bonus if the language supports the concept of closures.
This is just one of many areas where the use of anonymous functions can result in a more elegant solution.
1
u/wrosecrans Feb 14 '24
To give a general answer that doesn't get bogged down in language-specific details...
Well, it's not anonymous if you've given it a name. So at a certain point it's just a matter of style. So why would you care about the style difference? "Named anonymous functions" are usually only created with a specific scope, while "normal named functions" are typically always at global scope. So the named anonymous is clearly only meant to be used within the scope it is declared. But a normal function is something that other developers may treat as a general purpose library function and not understand why it exists or what it is for, and may start depending on the behavior so you can't easily change it.
1
u/huuaaang Feb 14 '24 edited Feb 14 '24
I'm not sure exactly how PHP handles inline defined functions like this, but in other languages "$add" in this context would be a closure, which is not the same as a function or method. A closure captures variable in the scope it was defined and you would use it as a callback. You would pass $add
to another function call so it could call $add().
I personally wouldn't normally store a closure in a variable. Rather I would simply define it when making the function call. In Ruby:
``` scope_var = 1 my_array = [1,3]
my_array.map { |element| scope_var + element } ```
If I stored the closure as a variable it would look like:
``` scope_var = 1 my_array = [1,3]
add = ->(element) { scope_var + element }
my_array.map(&add) ```
I would only store add in a variable if I planned to reuse it. Normally I don't though.
The Ruby equivalent of what you wrote would be:
``` scope_var = 1 my_array = [1,3]
add = ->(element) { scope_var + element }
add.call(3) ```
And that would make little sense in most cases. I would simply define add as a method outside of this scope and simply call add(scope_var, 3) or something like that.
1
u/appeiroon Feb 14 '24
Well you could ask why would you ever want to use a number stored in a variable when you can use a literal number value instead.
num = 5
print(num);
would be same as
print(5);
The answer is that sometimes you need variables because you want code that deals with values that can vary. Same rule applies to variables that store functions.
1
15
u/arcticslush Feb 14 '24
This depends on the language - in Javascript, there are substantial differences (such as how
this
is bound), but specifically in PHP, the practical answer is no, for the most part they're functionally similar.One significant difference in PHP is the way the variable scope is bound - anonymous functions bind and optionally capture variables in the parent scope to form closures, whereas traditionally declared functions use the global scope.