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