Live data from Hacker News

Perl code that is syntactically correct only on Fridays

github.com

71–80 of 233 posts

Re: Perl code that is syntactically correct only on Fridays

#71

Pro tip: add test cases to your CI runs with modified system date.

The thing is, you need to have a pretty corkscrew mind to think about cases like this. What date to change to? Far into the future? Far into the past? To a weekend? To a DST change? To Friday the 13th? To a US holiday? To a Muslim, Jewish, Chinese, Soviet, Albanian holiday? To a particular weekday? To Hitler's birthday? What if it's Lenin's? To that one day my coworker was depressed because the boss denied him a rais…

I feel obligated to link "Falsehoods programmers believe about time" - I think it's best to just get a trusty library instead. https://gist.github.com/timvisee/fcda9bbdff88d45cc9061606b4b...

Re: Perl code that is syntactically correct only on Fridays

#72
post #40

This is how it works: BEGIN { # an execution block that runs when the module is compiled *f = # assigns to the symbol "f" inside the symbol table ... (localtime->wdayname eq 'Fri') # is it Friday? ? sub() {} # ... on friday an anonymous subroutine taking no arguments : sub {}; # ... on every other day a subrouting taking arguments } # closes the execution block # The following line executes the subroutine "f" and div…

> # The following line executes the subroutine "f" and divides the result by 1 on fridays

> # but on other days causes the interpreter to trigger a syntax error

You have this the opposite way round to what's happening (and the description). It only compiles on a Friday, i.e. when the sub takes no arguments.

Removing all the "only on a Friday" stuff boils down to the difference between these two:

    # this compiles
    sub f() {}
    f/1;#/+

    # this doesn't compile
    sub f {}
    f/1;#/+
NB. the latter does compile if you take the `+` off the end, when it parses to (using -MO=Deparse)

    sub f {}
    f /1;#/;
When the sub is declared with zero args, `f` can only compile to mean "call f with no args", thus `/1;#+` means "divide the return value by one, end statement, rest is a comment".

However, when the sub does accept args, `f ` tries to compile `` into arguments to send - and it's a regex pattern `/.../` so the # isn't a comment, it's part of the regex, and the + is where modifiers go - but it's invalid, and is the syntax error. A valid pattern modifier would also compile, e.g.:

    sub f {}
    f/1;#/m
The argument to `f` here is "whether the pattern /1;#/ matched against $_":

    use feature 'say';
    sub f { shift ? "matched" : "unmatched" }
    $_ = 'this matches 1;#';
    say f /1;#/;
    $_ = 'this does not match';
    say f /1;#/;
Which prints:

    matched
    unmatched
So, it turns out the + needn't be characterised as an invalid modifier after all - it's just addition with a missing second operand. Add one in and it works as you'd expect:

    use feature 'say';
    sub f { int shift }
    $_='1;#';
    say f/1;#/+1         # prints 2

Re: Perl code that is syntactically correct only on Fridays

#76

Earlier quoted context omitted.

Personally I really don't like code that deals with time - it's too easy to place a "get time stamp" call anywhere in code. If it's down in the bowels of some piece of functionality trying to test it becomes a headache.

This is one of those pieces of software engineering wisdom that only comes from experience. Try explaining to a newish dev why they shouldn't `const now = Date.now()` or whatever anywhere they want, but rather do it in one place for the lifecycle and pass it around, and they will look at you funny and think it's a waste of time. Classic case of simple vs easy. Time has the potential to complect everything it touches.

I learned this the hard way. Now I wrap interactions with system time in a container class so that, if need be, I can finely control time inside my app in unit tests and debugging.

Re: Perl code that is syntactically correct only on Fridays

#77
post #43

Earlier quoted context omitted.

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 t…

It is formally proven that Perl can't be parsed! https://www.perlmonks.org/index.pl?node_id=663393

It can be externally parsed with ambiguities. The article is written by someone who authored such a parsing toolkit about three years later. Despite what you may have learnt, an ambiguous parse tree is still a useful thing to have, we can build tools taking it into account, also most existing tools can be modified in a straightforward fashion to make use of the extra nodes.

The real Perl parser disambiguates with heuristics and run-time hints.

There exists an unambiguous subset of Perl syntax that is expressible with a BNF grammar, and such is amenable to all parsers. http://p3rl.org/standard#DESCRIPTION

Re: Perl code that is syntactically correct only on Fridays

#78

I don't get it! It is clearly written in the code, that the progam should behave this way. Is the proof, that perl is capable of this behaviour?! I don't get it - what is the point? I read all the comments and still don't get it. What am i missing?

Was going to say the same thing. I thought it would be something wrong with the language. If you're going to write code that's different depending on the day of the week...meh.

Re: Perl code that is syntactically correct only on Fridays

#79
post #58
post #36

In similar vein: parsing C++ is literally undecidable: https://blog.reverberate.org/2013/08/parsing-c-is-literally-... You can't even decide if a particular "*" is multiplication or a pointer dereference until you resolve templates, which is Turing-complete.

Unless something has changed a lot, C++ templates at least only used to be Turing complete if you assume you're allowed unlimited recursive template applications, and compilers were free to restrict that (and did). Has that changed? In theory I agree with you that this is horribly ugly - I very much prefer simple grammars (the irony being my favourite language to use is Ruby, which has an atrocious grammar). In pract…

Well, C++ now has constexpr functions that can run in compile time, and do basically arbitrary computation. But it also has implementation limits.

Re: Perl code that is syntactically correct only on Fridays

#80

Earlier quoted context omitted.

Most other languages would require `eval` and having incorrect code as syntactically correct string literal. But because Perl is parsed as it is executed, incorrect code raises syntax error only when it is reached by execution.

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 t…

i can do something like this with macros in pike:

the following code produces a syntax error if the time is less than 10 seconds after a full minute.

    #define T __TIME__  
    #if T[6]-48
      #define X 1
    #else
      #define X /
    #endif

    void main()
    {
      write("%d, %c, %O\n", X, T[6], T);
    }
Post reply on HN