GummLANParty
Nothing Scheduled


[Go To Forum] | [Forum RSS]
100 Website/Forum Members
1229 Posts in 24 hours
1238 Posts in 7 days
12818 Total Posts
Chops is the last poster
Popular Threads
MouseSwitcher launched (8)
Election Predictions (217)
FOR SALE/TRADE post? (7)
Framed SSH program in linux? (9)
Congratulations on the wedding (12)
LAN Party set for November 3rd (11)





Get Firefox
PHP adds lambda functions and closures
[Coding/Tech]

[Back to Index]  [Bottom of Thread]
http://php.net/releases/5_3_0.php

About time. I absolutely HATED create_function for doing lambda functions. So much nicer.

----
Do it for the Lobster
Nice!

OT:How much LISP have you done?

----
I am no more an evolutionist than I am a gravatationalist or an electromagneticist.
Very little. Why do you ask?

----
Do it for the Lobster
Quote by Chops
Very little. Why do you ask?


Just the excitement over lambda functions.

----
I am no more an evolutionist than I am a gravatationalist or an electromagneticist.
Quote
Just the excitement over lambda functions.


Ahh. I've dealt with lambda functions plenty in other languages: javascript, lua, erlang (recently), and something else I think, though I can't remember specifics. I've also made some php framework-type stuff with the create_function function, which was a TOTAL pain in the ass.

I'm a big fan of lambdas.

----
Do it for the Lobster
Quote by Chops

I'm a big fan of lambdas.


Any good tutorials and examples? I've yet to fully grasp the lambda idea, I know python supports it and I might even be using it without knowing.

----
I am no more an evolutionist than I am a gravatationalist or an electromagneticist.
Tutorials, not sure. But I can give you examples from stuff I have running.

The basic thing to know about lambdas is that they are (in most languages that support them), no different than normal functions.

Taking javascript for example,

function my_alert(txt)
{
alert("my alert: " + txt);
}


Is no different than

var my_alert = function(txt)
{
alert("my alert: " + txt);
}


In most cases (in my experience), lambdas are "throwaway" functions - they'll be called once, or only within a certain scope.

A common example for this is something like a call to "map", which just applies a function to all members of an array or list, and returns the new list (rather than changing the existing list).

php has an array_map function, which is now made even better with lambdas.

Say you wanted to determine which elements of an array had integer square roots and return a list containing the integer square roots, or -1 if it's a non-integer square root (just for the sake of example).

You would normally (using the array_map function) do something like this:

$arr = Array(2,4,6,8,9,12,16);

function only_int_sqrt($v)
{
$sqrtval = sqrt($v);
return is_int($sqrtval) ? $sqrtval : -1;
}

$newarr = array_map(only_int_sqrt,$arr);



But, with lambdas, you could make it a little more succint:


$arr = Array(2,4,6,8,9,12,16);
$newarr = array_map(function($v){$s = sqrt($v); return is_int($s) ? $s : -1;},$newarr);


I recognize that that isn't TERRIBLY readable or obvious, but it's an example of somewhere that someone might use a lambda, assuming that's hte only spot in the code someone would want to apply that kind of filter.

I gotta leave for volleyball in a few minutes, so I tried squeezing in a pretty brief summary, but it looks like I'm going to run out of time.

The last part about lambdas (and one of the most useful) is about closures.

Closures are lambda expressions that have access to variables for which it shares scope, even if the scope has itself gone out of scope (or something like that).

Big example that I use most frequently: AJAX implementations and AJAX callbacks.

This is the ajax implementation that I use on this site. For practical purposes, you can ignore the "engineresponse" call part.

The general usage is like this

engine(callback_function,URL,[optional form contents of a post operation]);

It'll then send the request to the URL, and fun callback_function on the text of the response.



The thing to note though is this:

x.onreadystatechange = function() { if(x.readyState==4) ... };

The function still has access to variables outside of it's scope (the x variable). This means that the context of the function when it's called is kept along with the function itself.


As perhaps a more obvious example, I frequently make AJAX calls that I need to retain some state information when the browser receieves the response, and for that I'll do a small closure.

Say I wanted to retrieve the text of a single post via AJAX (say doing an inline edit or something) and post the results back into a div with id "post12345" where 12345 is the postid from the database, using the above function I'd do it like this:

//note: dge() is an alias I use for document.getElementById;

function retrieve_new_post(postid)
{
engine(function(resp){dge("post" + postid).innerHTML = resp},"getpost.php?postid=" + postid);
}


What makes that neat is that the function(resp) has access to the postid even AFTER the retrieve_new_post function finishes and goes out of scope. The engine() call returns immediately (it doesn't wait for the ajax call to complete), and then the function goes out of scope. But once the browser receives the response from the request, the closure gets called, and places the response text in the right div (getting the postid from it's context).


Before I understood closures, I do similar to above, but instead, I would include the postid in the response text then parse out the postid from the response. This way requires much less coding, is faster (though trivially so, I guess), and is more straightforware. Using a closure takes care of all of that, replacing the parsing step.

Am I making any sense? I just woke up like 30 minutes ago and I'm rushing because I have to leave for volleyball like right now.

----
Do it for the Lobster
Thanks! This will help tremendously.

----
I am no more an evolutionist than I am a gravatationalist or an electromagneticist.
Cool! Reading over that, I'm impressed you were able to make out what I was saying. I didn't have time to proofread that, and I realize fully how bad my explanations were.

I forgot one last use of closures, function generators (though I've never found a practical need for one yet).

When functions are first-class objects, you can also return a function, including lambda functions.

As a stupid example, consider this generally worthless function:


function welcome_alert(v)
{
alert("Welcome: " + v);
}



With Closures you can build a sort of generator for it.


function alert_maker(prefix)
{
return function(v) { alert(prefix + ": " + v) };
}


This function will create and return a new function.

So to see it in use, you could do this:


var welcome_alert = alert_maker("Welcome");
var bye_alert = alert_maker("Bye");
welcome_alert("lcde"); // alerts with "Welcome: lcde"
bye_alert("lcde"); // alerts with "Bye: lcde"


So it's pretty neat, but like I said, I've never used a function generator before, I don't think.


----
Do it for the Lobster
I read it a couple of times to get the jest. But I think its something I am going to have to come back to. heh

----
I am no more an evolutionist than I am a gravatationalist or an electromagneticist.
That's pretty awesome. I never knew the scope worked that way. I thought it was used in JS a lot so that you could redefine functions (since they are really just variables). The syntax is used heavily in JS and it's really cool that they added it to PHP5 now. It'll be nice when 5.3.0 gets enough penetration and I can start using that syntax. Of course, I'll probably be limited to use on my own machines for a while

----
no fat chicks


[Back to Index]  [Top of Thread]

Content of this site is © 2010 GummLANParty unless otherwise stated
Part of the SigmaSites Network.
© 2001-2010 Sigma Star Systems. All Rights Reserved.