Right, the beauty of this is that it's a syntax error he's produced. Sure any language can write code to produce a runtime error under any condition at all. And a lot of languages have features that allow them to run code at compile time, and similarly produce errors then too. But those languages don't allow you to ruin the syntax of the language. I guess it's something that requires macros. Would it be safe to say that any language with macros can do this? Or is there something even more interesting with perl going on here?
Common Lisp is another language in which this should be possible. Common Lisp allows you to run arbitrary code at compile-time, and that code is allowed to modify the language syntax (*READTABLE*, SET-MACRO-CHARACTER, etc). So code could make itself syntactically invalid on Fridays by changing the language syntax depending on the day of the week.
This goes beyond mere Lisp macros, in that ordinary Lisp macro invocations still look like Lisp lists, while with this you can make arbitrary changes to the syntax, you could even make Common Lisp look like Pascal (if you really wanted to)
The designers of Scheme intentionally left this feature out (which was also found in some of Common Lisp’s ancestors, such as Maclisp), but some Scheme implementations/descendants included it anyway (as an extension), such as Racket, Guile and Chicken Scheme.
But because Perl is parsed as it is executed, incorrect code raises syntax error only when it is reached by execution.
Sorry, but you're dead wrong. Perl is not parsed as it is executed, which can be verified easily by writing a program with a syntax error at the end, and seeing that it doesn't run code at the top. Try it with the following program.
print "Hello, world\n";
This line raises a syntax error before the previous line tries to execute.
What is going on is that BEGIN blocks are special, they are executed as soon as they are parsed. With them we can interleave parsing and execution.
In this case we're assigning to a symbol. And then the parsing of the final line is dependent on whether or not that symbol has a prototype. See https://perldoc.perl.org/perlsub#Prototypes for what Perl prototypes are, and to see why they would affect parsing.
>incorrect code raises syntax error only when it is reached by execution.
That's not generally true for Perl. The BEGIN block is used to get in that state here. "Some incorrect code raises syntax error only when it is reached" is true.
It's generating this on Fridays:
&f() / 1;
And this on other days:
f(/1;#/+);
If you run the same code, but without BEGIN blocking the assignment to *f, it isn't incorrect code. It evaluates as:
Perl is not parsed as it is executed. It is compiled to opcodes then run. The BEGIN block, however, explicitly runs code at compile time. It is literally compiling different code on different days, then attempting to run it.
JohnDeHope|4 years ago
skissane|4 years ago
This goes beyond mere Lisp macros, in that ordinary Lisp macro invocations still look like Lisp lists, while with this you can make arbitrary changes to the syntax, you could even make Common Lisp look like Pascal (if you really wanted to)
The designers of Scheme intentionally left this feature out (which was also found in some of Common Lisp’s ancestors, such as Maclisp), but some Scheme implementations/descendants included it anyway (as an extension), such as Racket, Guile and Chicken Scheme.
em-bee|4 years ago
the following code produces a syntax error if the time is less than 10 seconds after a full minute.
im3w1l|4 years ago
lloeki|4 years ago
https://www.perlmonks.org/index.pl?node_id=663393
btilly|4 years ago
Sorry, but you're dead wrong. Perl is not parsed as it is executed, which can be verified easily by writing a program with a syntax error at the end, and seeing that it doesn't run code at the top. Try it with the following program.
What is going on is that BEGIN blocks are special, they are executed as soon as they are parsed. With them we can interleave parsing and execution.In this case we're assigning to a symbol. And then the parsing of the final line is dependent on whether or not that symbol has a prototype. See https://perldoc.perl.org/perlsub#Prototypes for what Perl prototypes are, and to see why they would affect parsing.
tyingq|4 years ago
That's not generally true for Perl. The BEGIN block is used to get in that state here. "Some incorrect code raises syntax error only when it is reached" is true.
It's generating this on Fridays:
And this on other days: If you run the same code, but without BEGIN blocking the assignment to *f, it isn't incorrect code. It evaluates as:ars|4 years ago
Does the parse that happens on Thursday take precedence or is it reparsed every single time through the loop?
cestith|4 years ago
RandalSchwartz|4 years ago
petercooper|4 years ago