>
Having a blog about programming languages and formal methods I understand the basis of your disgust with PHP. In a perfect world all programming languages would use robust type systems and be capable of formal verification. PHP makes no attempt at either.Way to straw-man, dude! Nowhere did I suggest anything about perfect worlds or what programming languages should be like. I said that this particular feature of this particular language is undesirable because it introduces unnecessary complexity and risky levels of unpredictability into code that probably doesn't need to use it.
> Out in user land there are all sorts of scenarios where dynamic invocation makes sense. Higher-order functions are the most obvious. Is mapping strtolower on an array of strings really spaghetti code?
What does "dynamic invocation" have to do with higher-order functions? Pretty much everything described in the article deals only with functions as first-class values and unrestricted indirection. There is nothing "higher order" about them. If you're talking about implementing higher-order functions, then the only requirement is the ability to pass around functions as values. There is certainly no requirement for indirection on strings!
If functions are first-class values, that's absolutely fine. I'm complaining about situations where you end up passing names of functions around (as strings), and they take on special meanings along the way. I characterise this as spaghetti code because it leads to a situation whereby control flow is embedded both within constructs in the language, and within computed values based on using indirection on strings-indexing-functions. That's just nasty.
Just so I'm not misinterpreted, let me furnish my complaint with an example to show what I am and am not complaining about:
...
$x = "hello$z$k$y";
$x($foobar);
vs.
...
$x = function() { echo "foo"; };
$x();
The latter is (mostly) fine. The former is completely bonkers, and is what I am complaining about - the ability to do ad hoc indirection based on calculated values. In the first case, functions are
not values, and
strings have become semantically significant. In the latter case, the function
is a first-class value, and there is absolutely no magic going on - everything is hunky dory.
> Most uses for dynamic invocation are at the utility/framework level, not in application land.
I still can only think of a few restricted cases where indirection based upon strings (that values of which are not known until runtime) would be sensible or useful. The kinds of cases I can think of are where you would want to do something really dubious based on user-input. Keep in mind that I'm not railing against reflection here! Any sensible dynamic language should be able to provide you with the means to get a function value based on a name. This is not what you are describing. I think name-based reflection could have a use in utility or framework code, but relying on this kind of unrestricted indirection is really just a sign of deeper problems, I think.
> You're right, it's dangerous when used improperly
Which uh... was my point.
> but you should consider coming down from the theory clouds if you believe dynamic invocation and goto are in the same boat on the river styx.
Once again, you appear to be rebutting an argument I never made. Suggesting that I'm some sort of aloof theoretician is really a bit presumptuous. I developed an interest in all of those things you describe precisely because I am a programmer. Sure, I know a reasonable amount about theory, but I don't see that that should be used to discount any and all knowledge I have about practical programming too.
Let me make very clear my objection, once again. I am going to leave out exactly one definition from each of the following code snippets:
foobar(0);
vs.
$x(0);
I left out the definition of 'foobar' in the first snippet, and the definition of '$x' in the second. Can
you tell me where program control goes in each case?
In the first case, you know that it goes to a function named "foobar" somewhere within scope.
In the second case, of course you can't! You have to go figure out how $x has been computed. You basically have to read most of the code in order to find out what value $x will have just to be able to predict what the program will do next! This is basically the same problem that goto-style code creates - it makes it considerably more difficult to mentally simulate the execution of the program.
Edit: This is getting down-voted? Really? I would love to know why.