Wednesday 24 June 2015

PHP 7: IIFEs supported

I was unaware of this feature of PHP 7 until I accidentally discovered it whilst writing my previous article ("PHP 7: Three-way comparison operator (<=>)"). PHP 7 supports (Immediately-invoked function expressions).

My initial comparator function was thus:

// iifeExample.php

$oldScoreSorter = function($e1, $e2){
    $e1Value = $e1->getValue();
    $e2Value = $e2->getValue();

    if ($e1Value == $e2Value) return 0;
    if ($e1Value > $e2Value) return 1;
    return -1;

I wanted to use like a sgn() function, but PHP doesn't actually have one of those natively (yeah "WTaF?"), one has to install the GMP library to have gmp_sign().

So I rolled my own sgn() function within my comparator, to make what I was doing cleared (to ppl used to a sgn() function, anyhow):

$comparatorUsingSgn = function($e1, $e2){
    $sgn = function($x){
        return (int) ($x / abs($x));
    return $sgn($e1->getValue() - $e2->getValue());

I didn't like that as I'm only using the $sgn() function once, so it seems a shame to give it a name (well: other than self-documenting code, so Mark Drew - who has had me up about this before - would perhaps tut at me here).

My ignorance of PHP helped me here, cos I just went "well I dunno if PHP has IIFEs, but that's how I want to tackle this, so I'll try and see... it's just some copy and paste"):

$comparatorUsingIife = function($e1, $e2){
    return (function($x){
        return (int) ($x / abs($x));
    })($e1->getValue() - $e2->getValue());

As one might do with JavaScript (which also supports IIFEs), here I define the functionality, and simply call it straight away with some arguments. The syntax concession here is that one surrounds the function with parentheses, then call it immediately, eg:

$result = (function($x,$y){ /* do stuff */})($xValue,$yValue);

And it does whatever the function would normally do, including returning a value.

TBH, I don't think this is actually clearer than the long-hand version of the comparator, but it's good to know the technique is there should it make sense to use it.

Nice one. I've been wanting these in CFML for a while now. ColdFusion: 3950736; Lucee: LDEV-219.

Glad I "discovered" that.