(Just like many programs halt, even though it's proved that this is not the case for any input to any turing machine.)
(Just like many programs halt, even though it's proved that this is not the case for any input to any turing machine.)
Try this one:
#!/usr/bin/perl
BEGIN {
my $x = int(rand(2));
print "randomly picked $x\n";
if ($x) {
eval '
sub foo($) {
print "executed foo()\n";
}
';
}
}
foo / 25; #/ ; die "DIED\n";
print "DID NOT DIE\n";
This is technically parseable but only by thinking of it as a program that branches at every call of 'foo'. And think about what would happen if many such cases interacted."Modern" Perl programmers use a lot of syntax-perverting trickery, so this isn't as unlikely as it may appear.
just because a pathological case is possible, doesn't mean that it's actually common, or even existent.
Similarly it's possible to prove that a certain block of code does nothing but link in such deterministic units, removing the nondeterminism of function prototypes.
Most of the source code out there can be parsed statically without resorting to anything drastic. The semantics of this hypothetical Perl 5 variant do differ, but as a strict subset it will still properly most of the useful code out there.
Also, what you're describing is no longer static parsing.
"Modern" Perl programmers use a lot of syntax-perverting trickery,
so this isn't as unlikely as it may appear.
"Modern" Perl programmer do the complete opposite!This code completely ignores all the best practices that "Modern" Perl programmers adhere to so its is very unlikely to appear anywhere but in places like Perlmonks, Reddit & Hacker News ;-)
people using a 'sub ()' prototype for anything except a CONSTANT_NAME will be taken behind the bikeshed, shot, eviscerated, cremated, resurrected, shot again, and then told it's now their responsibility to project manage the repainting as penance.
Not true. The example he shows to not be statically parseable is:
whatever / 25 ; # / ; die "this dies!";
(because you need to know the value of `whatever' to parse it)1) Any programmer who writes this line of code as anything other than a lesson in obfuscation should be taken out and shot.
2) Speaking as a Perl programmer who has maintained others' code, _many_ Perl programmers should be taken out and shot.
How about: "Except for pathological constructs that should probably be avoided anyway, the Perl that most people write can be parsed just fine." As I see it, the Perl attitude is that these constructs should be forbidden by social contract rather than by the language itself. Sort of like the farmer who refuses to put a lock on his fuel pumps in case someone really needs to fill a tank in an emergency.
In most other languages with "dangerous" constructs, having the dangerous construct usually allows power that isn't possible using only safe constructs. Is it the case that this is useful in some circumstances, or is it just poor design?
But any code that is saved to a file and run more than once should lean a bit more toward clarity of expression. Three rules the pathological counterexample breaks: put parens around your function calls if they might otherwise be ambiguous; put =~ before a regexp if its identity might otherwise be unclear, and for heaven's sake put your line breaks in sensible places. This snippet exists to be pathological, and would quickly lose its ambiguity if written by anyone with reasonable habits of self-expression.
I am glad perl allows the balance between ruthless speed for programmer-efficiency and expressive clarity for maintainer-efficiency, for sometimes I write short one-shots and sometimes I write bulletproof modules, and I write many things in between.
But don't use habits suited to the former in the latter case. If you do that, perl will shoot you repeatedly until you either improve or shoot yourself. And if you survive, then you will have to deal with the folks who inherit your code.
Though I agree it's not a problem for actually trying to execute a Perl script.