Scriptorama.nl

Header image showing a keyboard, mouse, laptop and books on design patterns

PHP voorstel: Closures & Lambda functies

Sinds de PHP group het wiki gebruikt om o.a. voorstellen tot uitbreidingen van de PHP taal te verzamelen lijkt het wel voorstellen te regenen ook. Eerder hadden we al voorstellen voor Taint mode (waar het akelig stil over blijft, overigens) en Traits. Gister kwam daar een derde bij namelijk een voorstel voor closures & lambda's door Christian Seiler.

Wat zijn closures & lambda's

Lambda's en closures zijn in feite anonieme functies, functies zonder naam. In tegenstelling tot een gewone functie kun je ze dus niet 'gewoon' aanroepen, maar moet je ze toewijzen aan een variabele, of direct aan een functie die een callback als argument verwacht doorgeven.

PHP:
  1. $my_lambda = function($name) { echo 'Yeah, hi ', $name, '!'; }
  2. $my_lambda('mathieu');

Het idee is dat je ze gebruikt om het moment dat je eigenlijk wel een callback nodig hebt maar er eigenlijk geen echte functie voor wilt definiƫren, aangezien de betreffende situatie de enige plek is waar die functie gebruikt gaat worden.

PHP:
  1. $string='bac';
  2.  
  3.  '/~^([a-z]{2})/',
  4.  function($matches) { return strrev($matches[1]); },
  5. $string
  6. );

Het verschil tussen lambda's en closures lijkt het feit te zijn dat een lambda functie een closure wordt op het moment dat er gebruik wordt gemaakt van de scope die boven de gedefinieerde lambda ligt. Dit kun je in dit voorstel doen via het lexical keyword, deze importeert een variabele uit de bovenliggende scope (by-reference) naar de scope van de betreffende closure. Christian geeft daar zelf een mooi voorbeeld van:

PHP:
  1. function replace_in_array ($search, $replacement, $array) {
  2.      $map = function ($text) {
  3.        lexical $search, $replacement;
  4.        if (strpos ($text, $search)> 50) {
  5.          return str_replace ($search, $replacement, $text);
  6.        } else {
  7.          return $text;
  8.        }
  9.      };
  10.      return array_map ($map, array);
  11.    }

Zoals je ziet gebruikt de functie 2 variabelen ($search en $replacement) uit de functie replace_in_array(). Zonder een closure zou je voor dergelijke functionaliteit eigenlijk een eigen loop moeten schrijven.

Conclusie

Lambda functies & closures lijken me een nuttige toevoeging voor PHP. Ondersteuning voor 'anonieme' functies bestond al in PHP middels de create_function() functie, maar deze is beperkt (geen closures) en het kan lastig zijn om een wat uitgebreidere functie ermee te schrijven aan gezien je bijv. alle variabelen moet escapen.

De PHP ontwikkelaars hebben vooralsnog positief gereageerd op dit voorstel, maar hebben wel aangegeven dat het volgens hun beter is om deze functionaliteit, als het geaccepteerd wordt, naar PHP6 door te schuiven, zodat deze buiten Unicode ook nog nieuwe functionaliteit kan bieden.

Reageer ook!

Ik gebruik lambda's al tijden in javascript en moet zeggen dat ze erg praktisch zijn. Ik weet niet of het in PHP dezelfde zinvolheid heeft, maar ik denk dat het zeker bruikbaar is.

Ziet er inderdaad goed uit. Ben benieuwd of de PHP groep er ook zo over denkt. Maar heb liever eerst de traits :)

Over de stilte rond Taint:

http://devzone.zend.com/article/2798-Zend-Weekly-Summaries-Issue-368#Heading1

Is zeker interessant :D
Ik weet al een situatie waar ik ze kan gebruiken, preg_replace_callback()

Daarvoor moest ik nu een private function maken...

* Zit gelijk dat nummer, lambadabamba in me hoofd ;-) *

let erop, ze zijn iets anders geworden dan in dit voorbeeldje. Zie: http://phphulp.ikhoefgeen.nl/PHPhulp%20-%20PHP%20tutorials%20-%20PHP%205.3_%20Closures%20-%20Print%20version.pdf

Leave a comment
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>