On Sep 30, 2008, at 1:47 AM, Sean Conner wrote:

It was thus said that the Great Joshua Juran once stated:
On Sep 29, 2008, at 7:39 PM, Sean Conner wrote:

 -spc (Holding back the bile on a whole bunch of PHP hate ... )

No, no, by all means bring it forth!  :-D

  Gah!  Have I really been bitching about PHP since 2000?

I lasted only a few months in 2005. I knew PHP was popular, and SourceForge[1] used it, so it must be pretty cool (or at least decent), right?

I retained my sanity only by promising myself that I would never write another line of PHP, EVER. And much to my relief, I've forgotten most of it, freeing up mental capacity for things much more useful, like how to write head patches in 68K assembler, and much less offensive, like perl internals.

Have you ever tried
functional programming in PHP?

  No, I try not to program in PHP if I can help it.

I expect functional programming to be somewhat of a pain in the ass in C++, and I'm prepared to tolerate that. But in any modern scripting language it should be easy and just work, at a fair price, and probably give you closures to boot. But PHP is not just any modern scripting language.

First of all, you can't create anonymous functions. Now, doesn't that put the kibosh on things right there? No, not quite... allow me to introduce you to Create_Function(). Create_Function() is a glorified eval() that takes a string for the function parameters and a string for the function body, saving you the effort of concatenating them with the 'function' keyword and related punctuation yourself. It compiles the function at runtime and returns the new name that has been generated for it. I repeat: Although created at runtime, this is not an anonymous function -- it has a name, just one that's guaranteed to be unique, using a very clever technique that comes into play later.

So, not only does Create_Function() compile a new (identical) function each time it's called with the same arguments, but each such function is permanently installed in the symbol table until your script terminates. But it gets better: You probably want nice things like compose1() and bind1st(), right? Easy enough to write (assuming you're not one of the non-programmers making up PHP's target market). Oh, but you wanted them to work with created functions as inputs, too? Ooh, that could be a bit of an issue... you see, in addition to a monotonically increasing number, created function names contain a NUL byte. It's guaranteed that none of *your* functions' names contain a NUL byte because it's a syntax error in PHP. But doesn't that mean...? Yes. It means that your naive function adaptor will get a compile error at runtime because of the NUL byte in the name of an input function.

Fortunately, this is really simple to work around. All you have to do is, instead of passing to Create_Function() a text string which contains the literal function name with the NUL byte (e.g. "return Function\0_1( foo );", where \0 is an actual NUL), you replace it with an expression whose result is that string: In Perl, it would be "return Function" . chr(0) . "1( foo );". Now you can make *nested* calls to function adapters! Are we having functional yet?

Oh, did I mention that each *runtime* call to Create_Function() compiles a new function and leaves it lying around? Just around the time I was starting to get real work done (albeit pretty slowly) I managed to segfault apache via PHP.

And so, with whatever authority I've earned through this exercise, I classify PHP as a retro-programming language. After all, aren't its advocates fond of pointing out that you can do anything in PHP, since it's Turing-complete? Well, so is INTERCAL.

-spc (Good gravy! Is it really 4:45 am? What the heck am I still doing
        up?)

I have a good excuse, since I'm putting out version control fires.

[1] SourceForge has now broken my CVS use in addition to my project Web uploads, and will be the subject of a future hate.

Josh


Reply via email to