Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am beginning the process of moving code over to PHP 5.3 and one of the most highly touted features of PHP 5.3 is the ability to use closures. My understanding of closures is that they allow anonymous functions, can be assigned to variable names, and have interesting scoping abilities.

From my point of view the only seeming benefits in real world applications is the reduction of clutter in the namespace because closures are anonymous.

Am I wrong in this?

Should I be trying to put closures wherever I code?

EDIT:

I have already read this post on Javascript closures.

share|improve this question
up vote 4 down vote accepted

First off: Closures are not everything you describe as such. The concept of functions as first-class objects is related - although pretty much a prerequisite for closures - and anonymous functions are not really related (you usually have both in the same languages, but still, neither is required for the next).

I have come to the conclusion that to appreciate closures and to put them to good use, one needs to adopt a slightly more functional mindset. For example: When using higher-order functions (functions that return functions), the need for closures arises quite often (basically, every time the returned function needs to access the higher order function's arguments) and they are in fact the most natural solution. If you're writing a class to serve as an accumulator factory instead of a higher-order function, of course the closure won't fit in.

As a concrete example: I'm just writing a (small-ish, limited, kind-of) parser generator for XML defined in some relatively weird (but luckily, simple - XML abused as database, the kind of job JSOn or YAML does better) XSD offshot. The parsers returned are functions and about every one of the parsers is a closure (closing over the schema representation by which it parses). I'd rather not type up classes for all of this.

share|improve this answer
    
I'm not sure why I would create functions that would return functions. That may be why I'm not seeing the benefit? – Patrick Feb 1 '11 at 17:01
1  
@Patrick: Yes. As I wrote, seeing the point in closures (or most other tools from the functional programming world) requires some getting-used-to-it and practice to learn how to apply them. Of course it does - can a programmer who doesn't know the basics of OOP see the benefit of inheritance? No. Likewise, if you have little/no experience with functional programming, you propably can't apply closures. Perhaps you should learn a functional language? – delnan Feb 1 '11 at 17:04
    
ok, that makes sense. I just wanted to make sure I wasn't missing the point, and so I guess I'll read up on functional programming to get up to speed. thanks – Patrick Feb 1 '11 at 18:14

As a guy whose responsibility among other things is unit testing in php using PhpUnit, Closures are also you great friend for testing a code which was not written in the best regards of test.

About two months ago I took over a team who had been developing a project with no unit tests what so ever and decided to dedicate a few programmers to learn how to unit test and write the tests. The project had service locator all over it, and I had to find a solution on how to solve the problem and with the help of a SO user Elias Van Ootegem I was able to.


As mentioned in the post, you can also simulate parameters passed and returned through a reference.

Should you have a function to test:

public function ReturnIntAndChangeOutputParameter(&$outputParameter = false)
{
    $outputParameter = true;
    return 10;
}

You can use callback to simulate the parameter return:

$function = function(&$outputParameter)
{
    $outputParameter = true;
    return 10;
}

$classMock
    ->expects(/* */)
    ->method('ReturnIntAndChangeOutputParameter')
    ->will($this->returnCalback($function));

In fact, when writing unit tests, this is the only way how to do that, PhpUnit otherwise converts all variables to be passed by value even if the definition is pass by reference.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.