28 comments

[ 2.3 ms ] story [ 62.9 ms ] thread
Interesting and a worthwhile effort.
This is killer. Such a simple (and sharp) tool written for PHP is ideal for managing/debugging bloated framework/CMS X while also automating redundant-administrative operations from the bottom-up. Thanks for sharing; considering the potential of something this + Kohana could inspire some top-notch web apps, if not, at least some elegant back-to-the-basics way to code. EDIT: I think the expression I'm looking for is, straight-forward code control helps control project chaos, which is an inevitable side-effect for anything ambitious in PHP.
At the very least, using functional programming will raise the understanding bar for those who try to maintain those applications that use the paradigm.

However, I fail to see how this will improve the overall quality of PHP applications, nor how it is a return to "the basics," or how it will help maintain the myriad content management systems that are currently out there. Care to elaborate?

By 'the-basics' I was simply trying to say that a purely functional approach for any existing PHP implementation, whether it is a CMS, framework, application, etc. could help restructure the underlying architecture for whatever was originally implemented in straight PHP, somewhat like an API on the go. . .PHP has materialized some marvelous yet convoluted projects whose origin was not to solve a problem, but to do something very particular using HTTP, which at it's core, is what PHP does best.

I dunno, I guess I just think a functional paradigm could offer a faster and easier way for retooling existing PHP applications/frameworks that focus on what the application is supposed to do rather than how it's going to do it. Let PHP's extensive library worry about the system's protocol; this could help leverage your end-product as an API first, rather than opting-out of any further abstraction just to get what you think you want.

I dunno, I could be way off; I just think PHP is so matter of fact that attempting anything as abstract as what a purely functional language is capable of is nearly inexpressible.

This is why I appreciate YHacker News: Don't know when I would have run across this otherwise.

Futher comment shall wait until after my first hand dabbling in a new approach: In my next non-mission-critical PHP web hobbyist app.

Exactly. Even though lately there has been a lot of new users and a lot of meta discussion, there are still interesting posts like this one. Personally I have moved away from PHP and to Django, but I am looking forward to PHP 5.3.
Thanks for calling my post interesting. If it weren't for me having to deal with PHP at work, I wouldn't have even considered looking at PHP 5.3, but since I do, this represents a way for me to use PHP which is at least a little more consistent with the way I reason about programming in other languages such as Scheme (and in some ways Python, though map, and filter aren't 'Pythonic' anymore).
> "though map, and filter aren't 'Pythonic' anymore"

How come? I must have missed the memo...

list comprehensions take care of them. Guido wanted to remove them from Python 3.

   map = lambda f, a: [f(x) for x in a]
   filter = lambda f, a: [x for x in a if f(x)]
List comprehensions cover 90% of the use cases, but I'm glad map and filter were not removed. List comprehensions do not have first class status. You can pass map and filter around as arguments to other functions, but you cannot pass around "for", "in", and "if".
You're right, but even if they were removed, see above for their definition. :)
The real problem here is that the chances of PHP 5.3 being used in production anytime soon are rather slim. "Stable" distros, like Debian, Red Hat and CentOS, are still using PHP 5.1, which has long since been found to have issues that have been fixed and improved in PHP 5.2. Some hosts are still not even up to that level...

For open-source projects like what I'm working on, our need to support a wide variety of hosting environments means that we took flack even just dropping compatibility for PHP 4 and 5.0.

I would love to be able to start using some of the newer/better features arriving in 5.3, but sadly, PHP 6.1 will likely be out before I can ever start using those features in public projects... :(

My employer tends tends to upgrade to the latest stable release of PHP, so when PHP 5.3 comes up, we'll be upgrading. Since I rarely use PHP outside of work, this still will be worthwhile for me.

But, you're right. Significant changes in incremental releases like this makes it difficult for people to adopt, and I doubt that someone will bother backporting closures to a PHP 5.2.x release, like might be done in something like Python (from __future__ ... )

As for PHP 4 support, I thought that even Zend was done supporting it? Why is it still around?

> "As for PHP 4 support, I thought that even Zend was done supporting it? Why is it still around?"

Because there are still some applications and frameworks that do not support PHP4, either because no-one is working on them, or because certain incompatibilities between 4 and 5 would cause too much of the codebase to need to be rewritten. Sad but true.

Ubuntu comes with 5.2, so I'm assuming it'll adopt 5.3 rather quickly.
Unfortunately, Ubuntu doesn't represent the vast majority of production servers, because it's generally too bleeding edge. Production and hosting servers tend to stay on "tried and true" stable distributions, such as RHEL, CentOS, Debian, etc, regardless of how old the software versions contained.
It's worth noting that functions created via create_function won't be garbage-collected, which can cause some obvious problems.

This article about partial application may also be of interest to PHP hackers with an interest in functional programming.

http://metapundit.net/sections/blog/166

I personally use a wraper around php's create_function to predefine upto 6 parameters and also return the last statement.

  function lambda( $code )
  {
    if( !preg_match( '/return/', $code ) )
    {
      $code = preg_replace('/^(.*;(?!\s*$))?/s', "$1 return ", $code);
    }

    $code .= ';';
    $response = create_function('$_=null,$_1=null,$_2=null,$_3=null,$_4=null,$_5=null', $code);
	
    if( !$response )
    {
        error_log("lambda($code) failed");
    }
    return $response;
  }

This converts:

  $func = create_function('$v','return htmlenties($v,ENT_QUOTES);');
  array_map($func, $data);
Into:

  array_map(lambda('htmlenties($_, ENT_QUOTES)'), $data);
I'm taking care of this by memoizing them, at least when using Fn::lambda() to create a function with create_function. However, the whole return function() {}; should be garbage collected, since internally it's creating an object of type Closure with a magic method __invoke(). It's really quite the hack from what I've seen.
Since I use PHP at work, I've been waiting eagerly for closures since I first heard they'd be in 5.3.

Hopefully this stable release will have fewer issues than 5.1, and we can all upgrade quickly. I'm getting a little tired of cursing PHP's lack of lexical closures everyday (and I'm sure my co-workers are tired of listening to me complain).

Some days, all I wish is that PHP had a shortcut assignment operator:

  $var = $tom || 'ed';
What is that intended to mean?

Do you mean:

  $var = $tom ? $tom : 'ed';
If so, you can also do:

  $var = $tom or $var = 'ed';
If you don't want to calculate $tom twice.
Ars, the point is that $var = $tom || 'ed'; is much less verbose than the alternatives.

More generally, it's just strange to me that || and && don't operate the same in PHP as they do in every other C-style language. Neither does the ternary if, for that matter.

PHP 5.3 (and/or 6, I forget) gives us

    $var = $tom ?: 'ed';
I love how Groovy refers to that as the "Elvis" operator.
It seems like what the PHP team really needs to do is drop backwards compatibility with PHP4+ (on the road map for 6 maybe?), clean up the OO implementation, and then implement closures and anonymous functions.

What they need to NOT do is ridiculous things like this http://news.php.net/php.internals/41374.