7th March 2006

Posted in

Blog :: Frustration frustration

Today has been a day of frustration. Little things biting me. Somebody writing about programming languages (maybe it was Eric Raymond writing about learning Python) noted that friction in programming languages is part of what impedes your productivity: all the little details you have to learn where everything works a certain way except this one feature.

Hah. PHP has got a bunch of those. So many in fact that it's difficult to keep them all in your head. Today I have personally wasted time on the fact that php has weak dynamic typing.

I know, I know, this is one of the features of the language and something that everybody learns about first thing. But every so often it can come back to bite you where the sun don't shine. Consider the code fragment

 if("asdf"==0){ print "hello";}

What do you think this does? Why yes, you get a friendly greeting! The string gets cast to a number, any non-numeric strings are == to zero so yeah, "asdf" is the same thing as 0. This is most helpful when accepting input from forms where everything is a string and you can just use numeric operators on strings and any bad data gets thrown out, etc etc etc. I can almost convince myself it makes sense. Except then, of course, you have to invent the lovely === operator. Now if you program in a sane language, you may not have seen one of these before. This is the type equality operator which does not do automatic typecasting in the same way that the mere humble equality operator (==) does. And I can even see the rationale for this if I squint real hard: enable the sloppy way of comparing things by default ("1"==1) but let more advanced programmers deal with types if they like.

Until. What do you think is the result of this code?

$a=array(0,1,'a string');
$bool = in_array('asdf', $a);
var_dump($bool);

That's right. $bool is true! Why you ask? Well you don't have to, as I've just explained, any reasonable programmer can see that 'asdf' is the same thing as 0 and there is undoubtedly a zero in that array... Oh, you must have wanted the version of in_array that takes type equality into account: perhaps you should've passed the optional third parameter that forces in_array (and array_search) to behave SANELY.

Ahem. So PHP has these little pieces of rubbing. Chafing. Friction. I've demonstrated another one already in fact: see how I left the parentheses off of the "print" function call in the first example? That's because "print" isn't a function, it's a language construct like "require" so the parens are optional. Hows that a problem? Try passing print as a function. PHP implements function passing via strings. Yes, want to pass a function as a parameter? Simple, just pass a string containing the appropriate function name (with extensions to support passing static class or instanciated object member functions). <sarcasm>This makes functional programming a delight</sarcasm>: want to print the elements in an array? Just use

array_map('print', $a);

What do you get? No output and a warning: The first argument, 'print', should be either NULL or a valid callback

It took me 5 minutes of staring at the offending line to figure out what the error was talking about. Print isn't a function! Oh yeah. You think it is, you use it like it is, but it isn't. The accumulation of little things like this, all this cruft, makes programming in PHP less and less attractive to me lately.

Posted on March 7th 2006, 08:42 PM