[HN Gopher] Perl code that is syntactically correct only on Fridays
       ___________________________________________________________________
        
       Perl code that is syntactically correct only on Fridays
        
       Author : pabs3
       Score  : 410 points
       Date   : 2022-02-16 12:46 UTC (10 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | saba2008 wrote:
       | Somewhat related:
       | 
       | Perl Cannot Be Parsed: A Formal Proof (2008)
       | https://news.ycombinator.com/item?id=5770531
        
         | rabbits77 wrote:
         | Well, to be a little pedantic, Perl cannot be statically
         | parsed, since some constructs require runtime context.
         | 
         | If it could not be parsed it could never work!
         | 
         | And this is totally OK in my book, I use Perl for prototyping
         | ideas and an expressive language that allows creativity from me
         | the programmer is a feature as it promotes looking at a problem
         | from multiple aspects.
        
           | avgcorrection wrote:
           | "Cannot be X" most often means "in the general case". (In the
           | context of computability.)
        
           | lmm wrote:
           | > Well, to be a little pedantic, Perl cannot be statically
           | parsed, since some constructs require runtime context.
           | 
           | If you're going to be pedantic, it's important to be correct;
           | there's no such thing as dynamic parsing.
           | 
           | > If it could not be parsed it could never work!
           | 
           | What's the logic here? An interpreter doesn't have to operate
           | on an AST, a language doesn't have to have a nontrivial
           | grammar (consider Brainfuck). Perl is just a language in the
           | same category: it doesn't have a (true) nontrivial AST, it
           | doesn't have a (true) nontrivial grammar, and it can't be
           | (truly, nontrivially) parsed.
        
             | samatman wrote:
             | > _there 's no such thing as dynamic parsing_
             | 
             | As long as we're indulging in pedantry, this is incorrect
             | presuming dynamic means what it usually means. Any regular
             | expression constructed at runtime contradicts you.
             | 
             | Modifying your core parser at runtime though, who would do
             | such a thing? Other than reader macros in Common Lisp I
             | mean. Are we going to argue this means Common Lisp doesn't
             | parse if we add reader macros at runtime? A peculiar
             | argument.
             | 
             | Now. Should we talk about whether doing that is a good
             | idea? A lovely and separate conversation. I agree with GP
             | that since Perl will spit out a parse tree, it does in fact
             | parse, and since it's not static, well, it's dynamic.
             | 
             | Which we can prove by, I dunno, writing some Perl which
             | only parses on Fridays. Right?
        
               | bmn__ wrote:
               | > Modifying your core parser at runtime though, who would
               | do such a thing?
               | 
               | Perl? Its numerous language extensions allowed it to stay
               | competitive for such a long time. Every time someone says
               | "language X can do Y but Perl doesn't have that syntax",
               | a new CPAN module is born to amend the shortcoming.
        
               | lmm wrote:
               | > Are we going to argue this means Common Lisp doesn't
               | parse if we add reader macros at runtime? A peculiar
               | argument.
               | 
               | Peculiar how? Isn't that just common sense?
        
       | gvb wrote:
       | <pedantic>
       | 
       | The code is never syntactically correct however the syntax error
       | is not identified by the Perl interpreter on Fridays.
       | 
       | </pedantic>
        
       | jordanmorgan10 wrote:
       | Gah why did I take up programming for a living :|
        
       | Leherenn wrote:
       | I have seen some code that would fail based not on time but
       | location.
       | 
       | Once we had a client from the Netherlands that complained about a
       | bug that we could not reproduce. We tried to reproduce it by
       | simulating his position, but to no avail. Turns out he was in a
       | very specific, slightly depressed, area that was a few
       | centimetres below mean sea level and that the code didn't like
       | negative altitudes.
       | 
       | Another one only happened in the southern hemisphere. Given we
       | were based in Europe and it was winter, we asked whether we could
       | do some more tests in Australia to make sure there were no more
       | bugs, but sadly it was denied.
        
       | reneberlin wrote:
       | 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?
        
         | iLoveOncall wrote:
         | What makes it "special" here is the fact that it will COMPILE
         | only on a friday.
         | 
         | It's not a runtime error but a compile time error. Because yes
         | otherwise I would agree that it's doable easily in every single
         | language.
        
           | high_pathetic wrote:
           | Isn't perl an interpreted language? Or I am missing a point?
           | 
           | What will happen when the command is `perl -c friday.pm`?
        
           | ghayes wrote:
           | But isn't this possible with any language that has a pre-
           | compilation step? Perl is certainly conflating its passes (as
           | explained by other comments above), but in rust you could add
           | a check in build.rs or use macros in C to accomplish the
           | same, right?
        
           | bachmeier wrote:
           | Here's a D program that only fails to compile if the last
           | digit of the current number of seconds is 4:
           | 
           | enum timestamp = __TIMESTAMP__;
           | 
           | void main() { pragma(msg, timestamp[$-6..$-5]); auto a = 4;
           | static if(timestamp[$-6..$-5] == "4") { auto a = 7; } }
        
         | JohnHaugeland wrote:
         | they made a branch where one side is defective and the other
         | isn't
         | 
         | they only follow the non-defective side one day a week
         | 
         | because perl doesn't forward analyze, it never sees the error
         | on other days, and doesn't fail
         | 
         | the presentation is false. this code is always wrong. it's just
         | that the bug is only visible under certain conditions.
        
         | bachmeier wrote:
         | 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.
        
         | wutbrodo wrote:
         | You can write code in any language that fails at runtime
         | depending on the day. What's notable about this is that its
         | _syntactical correctness_ depends on the day, which is not
         | possible to achieve in many languages.
         | 
         | What's being noted is the degree of flexibility that Perl has
         | with respect to its execution environment.
         | 
         | Though if you include preprocessors, you expand the number of
         | languages for which you can do something similar.
        
       | JohnHaugeland wrote:
       | This code is always syntactically incorrect.
       | 
       | It is merely that the problem branch is only occasionally
       | followed.
        
       | praptak wrote:
       | 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.
        
         | vidarh wrote:
         | 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
         | practice these parses are rarely that hard to resolve.
        
           | praptak wrote:
           | It's not the undecidability itself that is the problem
           | though. The undecidability is just an indicator how horribly
           | complicated C++ is to compile.
           | 
           | You cannot even construct the full parse tree before
           | evaluating a mini-language that is Turing complete. Related
           | article: why C++ compilation is slow
           | (https://digitalmars.com/articles/b54.html)
        
             | vidarh wrote:
             | I have a half-finished Ruby compiler sitting around, so I'm
             | a bit jaded when it comes to how complicated something is
             | to compile. C++ is complex, but at least it's reasonable
             | well specified.
        
           | steerablesafe wrote:
           | Well, C++ now has constexpr functions that can run in compile
           | time, and do basically arbitrary computation. But it also has
           | implementation limits.
        
         | ncmncm wrote:
         | Compilers decreasingly encounter parses that depend on template
         | instantiation, as users move to new constexpr alternatives to
         | template metaprogramming.
         | 
         | So the right implementation choice, for the compiler, is to
         | bull ahead with the common case, and throw the result away and
         | try the other path if you get to an inconsistency. Such
         | inconsistencies practically never happened in production code
         | anyway, and where they did it most usually was, and now almost
         | always is, a result of a bad edit.
         | 
         | So the practical expense is keeping and then GCing old state as
         | it expires, which reduces to stack-like memory management, a
         | solved problem.
         | 
         | We have not needed to go to JITting compile-time constructs,
         | (though it could still happen to expedite constexpr
         | evaluation). Rust might need to, soon, to accommodate parsing
         | under influence of macros, a chore growing with time, not
         | shrinking. (I.e., produce a new parser for each macro added,
         | and jump into it to finish the parse.)
        
       | johnnyo wrote:
       | I had an intern once who wrote similar code. They confused 12
       | hour and 24 hour clocks, so the code would break after lunch.
       | 
       | Unfortunately, the intern only worked the mornings, so it took
       | several days of back and forth before the bug could be finally
       | put to rest.
        
         | [deleted]
        
         | markstos wrote:
         | We had situation where if you worked late, the test suite would
         | consistently fail.
         | 
         | Since developers rarely worked late and would give up when
         | hitting the "random" test suite failure and go home, the bug
         | persisted for months before the true cause was understood.
         | 
         | Our time zone was UTC-5, and the test suite contained a local-
         | vs-UTC bug which only triggered between 7pm and midnight.
        
           | monkpit wrote:
           | I feel like this is relatively common (unfortunately)
        
             | Nextgrid wrote:
             | It is. I'm in London which means that our time is +/- 1
             | hour of UTC depending on daylight saving time.
             | 
             | There's been a couple projects where if I pushed a commit
             | between 11pm and 1am some tests would break. I'm pretty
             | sure the issue is inconsistent use of UTC vs local time
             | which during that period will differ by one day.
        
               | ipsi wrote:
               | One of the perils of working in the UK is _assuming_ that
               | you've been using UTC timestamps this whole time, and
               | then summer rolls around and suddenly a bunch of tests
               | start failing, and all your production logs are an hour
               | out because you were wrong, and actually used local
               | timestamps everywhere. Oops.
        
         | knodi123 wrote:
         | Ha. I had an intern who wrote code that blew up if the
         | timestamp of our DB server was ever >= 1 second _after_ the
         | timestamp of our app server.
         | 
         | It couldn't fail at his desk, because he ran both servers
         | locally while developing. And it wouldn't fail in production in
         | the morning, since we had a cron job that synced the clocks at
         | midnight. It took until after 5pm for the clocks to drift
         | enough, meaning I was on call and the intern was not.
         | 
         | But the bug didn't crop up until his code had been in
         | production for a couple of weeks, so it was a real pain in the
         | neck to track down.
        
           | inquist wrote:
           | > an intern who wrote code .... his code had been in
           | production
           | 
           | You get what you pay for, eh?
        
             | mypalmike wrote:
             | Depends. FAANG interns can make (annualized) income at or
             | near 6 figures.
        
             | mywittyname wrote:
             | I've done equally stupid things as a senior dev. The
             | biggest difference, I guess, is that I had to fix the stuff
             | I broke.
        
             | [deleted]
        
             | twopsix wrote:
        
             | darkwater wrote:
             | A cronjob to sync the time instead of a proper NTP client
             | doesn't sound that good either. I know that each place has
             | its own weird things because historical reasons but NTP is
             | quite ancient.
        
               | knodi123 wrote:
               | Our sysadmin was being paranoid about how many memory-
               | resident programs we ran. he figured time syncing wasn't
               | important enough to justify a daemon, so he just ran the
               | ntpdate command on a daily schedule. It wasn't _that_ bad
               | - after all, how far can clocks drift in a single day!?
               | ;-)
        
               | xorcist wrote:
               | If you are to be paranoid about time, better be paranoid
               | about stepping time. Time discontinuities can trigger
               | bugs in the best of software.
        
               | tristor wrote:
               | > he figured time syncing wasn't important enough to
               | justify a daemon
               | 
               | Time synchronization is very arguable THE most important
               | thing on a server (for numerous security related
               | reasons).
               | 
               | How many moons ago was this incident? It's perhaps
               | forgivable ignorance in the 90s... not so much today.
        
               | Dylan16807 wrote:
               | For security? Kerberos usually has a 5 minute tolerance.
               | Are you saying that's wrong? Because if your
               | hardware/firmware isn't literally broken you won't drift
               | anywhere near that in a day.
               | 
               | NTP can't properly fix a clock like that either since
               | it's often capped at adjusting the speed by one part per
               | two thousand. At most, with a consistently wrong clock,
               | that can handle about 30 seconds per day. Any worse than
               | that and you won't see much advantage over ntpdate.
        
               | shadowoflight wrote:
               | Guess it's time to change the `0` in that cronjob to a
               | `*/12`.
        
               | krick wrote:
               | Admin like that sound a lot worse than the intern. Unless
               | maybe if it's an intern-admin...
        
           | amelius wrote:
           | To be honest, I wrote code that blew up after the time server
           | updated the time from the network, a few seconds after
           | booting.
        
           | bentcorner wrote:
           | 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.
        
             | [deleted]
        
             | sandinmyjoints wrote:
             | 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.
        
               | fegu wrote:
               | In Haskell, getting the time is an IO operation. Because
               | of this one tends to use the exact pattern you recommend.
        
               | kodah wrote:
               | > Classic case of simple vs easy.
               | 
               | Personally, I think my definition of "simple" changed
               | over time. Much of that was influenced by the depth of my
               | knowledge of particular paradigms, whether that be
               | software or knowledge of the subjects I was writing code
               | for.
        
               | albrewer wrote:
               | 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.
        
               | Spoom wrote:
               | Oh yes. Any time I see code that tries to do some kind of
               | scheduling, the first thing I ask is if they have
               | considered using a library someone else has written. Way
               | too many things can subtly go wrong, but new folks tend
               | to think it should be easy, because how hard can it be to
               | work with dates?
        
               | duxup wrote:
               | > because how hard can it be to work with dates?
               | 
               | Man they are so hard that you could go on for hours about
               | it.
               | 
               | https://www.codingblocks.net/podcast/why-date-ing-is-
               | hard/
        
               | munk-a wrote:
               | There are seven time zones in Indiana in the tz
               | database[1] - this doesn't count the two most used ones
               | America/Chicago and America/New_York there's also a
               | Kentucky tz that slightly spills into the state. Whenever
               | anyone makes any comment about dates and times being easy
               | to compute I just mention that yes, _there are seven time
               | zones in Indiana_. Now the actual issues tend to arise
               | when software makes assumptions like  "every second will
               | actually occur", "each second only happens once", "every
               | minute has 60 seconds", "every day has 86400 seconds"
               | amongst a plethora of other bad assumptions... but those
               | are a lot more complicated to explain. I like leaning on
               | Indiana.
               | 
               | 1.
               | https://en.wikipedia.org/wiki/Time_in_Indiana#tz_database
        
               | VTimofeenko wrote:
               | A great collection of those "every minute has 60 seconds"
               | assumptions and why they are incorrect:
               | 
               | https://yourcalendricalfallacyis.com/
        
               | tentacleuno wrote:
               | > because how hard can it be to work with dates?
               | 
               | Oh man, tell me about it. Timezones are the worst. No
               | wonder so many people just give up and use Moment.js.
        
               | dheera wrote:
               | Use UTC UNIX timestamps (i.e. Date.now()) for ALL time-
               | related processing and only convert to hours/minutes when
               | taking input/output from the user.
        
               | anchpop wrote:
               | Hmm, I think you should use TAI over UTC because UTC has
               | leap-second corrections, Which means that the current
               | time + X seconds might not actually be X seconds from now
        
               | aidos wrote:
               | Uh oh, we're going there again. If you're doing anything
               | in the future, that's not always the correct thing to do.
               | (Instants vs wall time etc)
        
               | mypalmike wrote:
               | That's a good starting point, and certainly good advice
               | for marking current time and past times. But keep in mind
               | that future event absolute UTC can change due to
               | politics, e.g. a change in daylight savings rules, which
               | is less rare than you might imagine (https://en.m.wikiped
               | ia.org/wiki/Daylight_saving_time_by_coun...). That
               | concert scheduled a year from now at 8pm in UTC+5 might
               | actually end up occurring at 8pm in UTC+6.
        
               | jwandborg wrote:
               | I've been bit by bugs when coming to moment.js from other
               | languages. It's the only datetime library I knew of,
               | before you'll tell me about all the others, that mutates
               | the datetime object when you do arithmetic.
        
               | blowski wrote:
               | The PHP interops group recently added a Clock interface
               | for this purpose. There were many comments along the
               | lines of "what's the point?"
        
               | bitemix wrote:
               | Love the Rich references.
        
               | lordnacho wrote:
               | It's also one of those things that actually is simple in
               | restricted cases, then when you try to generalise it
               | blows up badly, and it blows up like a time bomb rather
               | than a landmine. When a time bomb explodes you don't
               | quite know when it was triggered, but you have to deal
               | with it then and there, learning a heck of a lot about
               | time libs in general before you can proceed. What's a
               | leap second, which years have a leap day, are time zones
               | connected to places somehow, and so on. Just so you can
               | fix your calendar that's part of a larger app.
        
             | jimmaswell wrote:
             | Not too bad testing these things with mocking libraries.
        
         | actually_a_dog wrote:
         | It could have been much worse. At least you didn't have a leap
         | year or timezone bug. I've exterminated more than one of those
         | in my time as an engineer, and it's never really any fun.
        
         | divbzero wrote:
         | Like many here, I've faced similar challenges in debugging
         | time-dependent code.
         | 
         | What is the best way to set or mock system time during testing?
        
         | anned20 wrote:
         | If you tried, you couldn't even come up with this.
        
           | RandalSchwartz wrote:
           | I could. :)
        
         | lanstin wrote:
         | I had a coworker working on a data-pipeline sort of thing once.
         | They for some reason wrote their own date parser (Akamai logs)
         | and used a regular expression to find the month. For whatever
         | reason, the RegExp didn't work for March (I think) and so at
         | midnight 1 March the year of first deploy, we started dropping
         | all the logs as un-parseable (causing the NOC to think the
         | traffic had gone to 0 or our system was buggy). We all got
         | paged and eventually figured out it. It had been running in
         | live for several months without problems at that time.
        
         | usrusr wrote:
         | Fortunately we rarely use 12h clocks where I live. But that
         | opens up other avenues: if you are not much of an early riser,
         | a build script failing to deal with single digit hours can
         | remain undetected for a _very_ long time.
        
         | ihateolives wrote:
         | I once had to implement date picker that returned the date to
         | be sent to backend to fetch the day's reservations. It seemed
         | to work fine the day I implemented it. Next day it broke.
         | Turned out the widget returned MM/DD/YYYY instead of
         | DD/MM/YYYY. And I implemented it on 10th of October.
        
           | adhoc_slime wrote:
           | I've learned the hard way that this is also dependent on the
           | user's date format set on their computer in some
           | libraries(iirc it was jquery ui date picker a few years
           | back). its liberating when you decide to throw it all out and
           | just use integers for all things not facing an end user.
        
           | mark-r wrote:
           | I'm a big fan of ISO 8601. Eliminates the confusion, and
           | sorts lexicographically too.
        
           | PixelOfDeath wrote:
           | Aliens landed on this planet, found out about the date format
           | MM/DD/YYYY, and left in a hurry. They are currently preparing
           | a gamma ray burst out of pure compassion and pity but also a
           | hint of disgust!
        
             | Ma8ee wrote:
             | Is that date format used anywhere outside the US? We have
             | always used YYYY-MM-DD. Which is very nice, if for nothing
             | you can use a single string sort if for whatever reason
             | need to sort them.
        
               | ant6n wrote:
               | In my world, there are two date formats: yyyy-mm-dd and
               | dd.mm.yyyy.
               | 
               | Anything involving a slash is asking for trouble.
        
               | tzs wrote:
               | https://en.wikipedia.org/wiki/Date_format_by_country
        
         | wumpus wrote:
         | One perhaps apocryphal story that's kicking around out there
         | was that Draper Labs had a hard-real-time navigation system
         | which... took too much time computing something when the moon
         | was full.
        
         | nitwit005 wrote:
         | Saw some tests that had the same pattern. Passed half the day,
         | and failed the other half of the day. I assume it always worked
         | during India work hours.
        
         | alisonatwork wrote:
         | Fantastic. We had a similar problem with test code that always
         | worked on a remote team's computers during their work day but
         | failed when we got into the office and tried to run it in a
         | different timezone.
        
           | pc86 wrote:
           | Reminds me of an app I worked on a while ago where both the
           | server it was running on and the datetimes in the database
           | had to be in a specific time zone. Change either (including
           | changing both to an identical but different TZ) and the app
           | just failed to run.
        
           | vidarh wrote:
           | I've had to fix any number of test suite bugs as well as
           | regressions that happened because the people who wrote the
           | tests had ensured the test suite didn't (most of the time)
           | test what they thought it would by relying on date arithmetic
           | from current date and time...
        
             | salawat wrote:
             | Many people think that test suite authoring is easy mode.
             | It really isn't. Making a good test suite that actually
             | does a good job of tracking invariants is a royal pain.
        
               | ljm wrote:
               | As far as I'm concerned, writing tests is a different
               | skillset and its often underdeveloped. It then snowballs
               | into hating testing, because all you've experienced is a
               | poor test suite that gets worse over time. It's hard to
               | do well as you say, and it also gets glossed over in code
               | review as long as the tests pass. Do the tests actually
               | verify anything useful? Who knows, build is green!
               | 
               | That's how you get an application with 50,000 unit and
               | integration tests that you can't run locally, and
               | requires massive parallelism in CI to finish in any
               | reasonable timeframe.
        
         | manojlds wrote:
         | That's standard runtime issue right? This is syntax error at
         | compile time.
        
           | dhosek wrote:
           | Kind of sort of. The catch here is that because runtime is
           | compile time with Perl, it's not exactly the same. Looking at
           | the code, it's kind of like having something like
           | #if (some C preprocessor expression that's true on Fridays
           | printf("Hello world!);         #else            printf;
           | #fi
           | 
           | (although it's been long enough since I've written C that I
           | don't know if (a) there exists a C-preprocessor instruction
           | as per the above, (2) if the compiler will notice errors in
           | the unexecuted branch of an #if and (iii) if printf; would
           | give a syntax error).
           | 
           | Another equivalent piece of code could be something along the
           | lines of the JS                   if (today_is_friday()) {
           | eval("2+2")         }         else {           eval("--2abc")
           | }
        
             | garaetjjte wrote:
             | >(a) there exists a C-preprocessor instruction as per the
             | above
             | 
             | There's no day-of-week but you could cause mayhem with
             | __DATE__
             | 
             | >(2) if the compiler will notice errors in the unexecuted
             | branch of an #if
             | 
             | Compiler only gets to see preprocessor output, it won't.
             | 
             | >if printf; would give a syntax error
             | 
             | Perhaps surprisingly but no, it's just statement without
             | effect (containing expression returning function pointer to
             | printf).
        
               | nousermane wrote:
               | > you could cause mayhem with __DATE__
               | 
               | It takes some patience, but people do try:
               | https://stackoverflow.com/questions/11697820#16472369
        
             | [deleted]
        
       | brian_herman wrote:
       | python:                 import datetime        if
       | datetime.datetime.now().weekday() == 3:           1/0
        
         | jwilk wrote:
         | Once you fix the indentation, this code is always syntatically
         | correct; it just happens to raise an exception on Thursdays.
        
       | cube00 wrote:
       | Another great reason not to deploy on Friday.
        
       | athenot wrote:
       | This leverages Perl's BEGIN block which runs before the main part
       | of the code. I suppose the same fun could be had in other
       | languages:                   if day_of_week is "Friday"
       | eval(piece_of_incorrect_code)         else
       | do_sane_operation
        
         | saba2008 wrote:
         | 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.
        
           | btilly wrote:
           | _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.
        
           | petercooper wrote:
           | Ruby has that latter quality in many scenarios. For example:
           | p 'Friday!' if Time.now.wday==5 || h
        
           | JohnDeHope wrote:
           | 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?
        
             | im3w1l wrote:
             | Bash parses as it runs so something as simple as this works
             | if [ $(date +%u) -ne 5 ]       then         exit       fi
             | (
        
               | jwilk wrote:
               | You could check syntax of the whole file (even the
               | unreachable parts) with the -n option.
               | 
               | But that's not bulletproof; consider this code (adapted
               | from <https://hal.archives-
               | ouvertes.fr/hal-01513750/document>):                 if [
               | $(date +%u) -eq 5 ]       then           alias maybe=''
               | else           alias maybe=:       fi       maybe for x
               | in; do :; done
               | 
               | "sh -n" always reports syntax error, even thought the
               | script syntax is correct on Fridays.
        
               | lloeki wrote:
               | Bash even reads the file as it goes, so if you run a
               | "long-running" script (a sleep is enough), edit far
               | enough down, and write the file again, the previously
               | started bash will end up running the new content once it
               | gets up to reading where the change happened.
        
               | saba2008 wrote:
               | You can exploit it do distinguish whenever script is
               | `curl | bash`'ed.
               | 
               | Add `sleep 1`, and detect pause on server. Then, if pause
               | detected - serve attack payload. If not - somebody is
               | careful enough to download and audit, so serve just the
               | script.
        
               | jwilk wrote:
               | https://www.idontplaydarts.com/2016/04/detecting-curl-
               | pipe-b...
               | 
               | Discussed on HN:
               | 
               | 2020: https://news.ycombinator.com/item?id=25356757 (133
               | comments)
               | 
               | 2018: https://news.ycombinator.com/item?id=17636032 (146
               | comments)
               | 
               | 2016: https://news.ycombinator.com/item?id=11532599 (122
               | comments)
        
             | lloeki wrote:
             | It is formally proven that Perl can't be parsed!
             | 
             | https://www.perlmonks.org/index.pl?node_id=663393
        
               | bmn__ wrote:
               | 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
        
               | lloeki wrote:
               | Yeah, I always found the linked post to not be all that
               | serious about it anyway, just a funny, satisfying hacker
               | thing.
        
               | RandalSchwartz wrote:
               | It has been said that "the Perl compiler is based on
               | yacc, lex, smoke, and mirrors."
        
             | em-bee wrote:
             | 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);         }
        
             | skissane wrote:
             | 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.
        
           | tyingq wrote:
           | >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:
           | 'f' / 1;
        
             | ars wrote:
             | What happens if you run this code in a loop Thursday night
             | just before Friday?
             | 
             | Does the parse that happens on Thursday take precedence or
             | is it reparsed every single time through the loop?
        
               | tyingq wrote:
               | The BEGIN block only runs once. That is:
               | while (1) {         BEGIN {print "hello\n"}         sleep
               | 1;       }
               | 
               | Will only print "hello" one time.
               | 
               | You could loop inside the BEGIN block and then drop out
               | of the loop at some point. If you dropped out on friday,
               | after the code assigning *f, it would run correctly. So:
               | BEGIN {            sleep 86400;            *f =
               | (localtime->wdayname eq 'Fri')             ? sub() {}
               | : sub {};       }       f/1;#/+
               | 
               | Would run correctly if you started it on Thursday.
        
           | cestith wrote:
           | 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.
        
             | RandalSchwartz wrote:
             | Technically not opcodes, but internal Data Structures. A
             | serializer was written for that, to permit ".pmc files".
        
               | cestith wrote:
               | Oh, hey, Randal. Thanks for the correction.
               | 
               | Looking forward to the next time we can have steaks and
               | Scotch.
        
         | yodon wrote:
         | Moral quandary of the morning: Do I point out the sign error or
         | do I just say please don't merge this?
        
         | runeks wrote:
         | That looks like a syntactically correct piece of code that
         | fails at runtime.
        
       | edgyquant wrote:
       | I miss Perl and it's community from the early-mid 2000s. Sure it
       | was bad for those who have to maintain but trying to create the
       | shorted and most unreadable possible was a fun pastime.
        
       | draw_down wrote:
        
       | me_again wrote:
       | I had a program once which failed every time it was 8 or 9
       | minutes past the hour and worked the rest of the time.
       | 
       | It parsed a string containing the time and sscanf treats "08" and
       | "09" as invalid octal numbers. Argh.
        
         | mrspuratic wrote:
         | Been there, a TCL web script, IIRC. This led to religious
         | processing of input with "regsub" (this predated TCL 8). Yuck.
         | 
         | Also once fixed an inherited awk script that malfunctioned at
         | the end of year: a hardcoded month name array with November
         | missing. To this day I always populate any such lookup with a
         | loop and strftime() or appropriate.
        
       | pera wrote:
       | heh as soon as I saw the ternary expression I recalled the bug
       | report I submitted some years ago:
       | 
       | https://rt-archive.perl.org/perl5/Ticket/Display.html?id=130...
        
       | didip wrote:
       | Wow. Do I need more reasons to hate perl?
       | 
       | Yes, apparently.
        
       | kazinator wrote:
       | C code in similar spirit:                 $ gcc weird-0.c       $
       | ./a.out
       | 
       | No output from weird-0                 $ gcc weird-1.c       $
       | ./a.out       foo(42)
       | 
       | Output from weird-1. What is weird-0?                 $ cat
       | weird-0.c       #include <stdio.h>            void foo(int x)
       | {         printf("foo(%d)\n", x);       }            int x = 42;
       | int main(void)       {       #if __LINE__ % 2 == 0
       | typedef int foo;       #endif         foo(x);         return 0;
       | }
       | 
       | OK, how does weird-1 differ from weird-0? One blank line!
       | $ diff -u weird-0.c weird-1.c       --- weird-0.c 2022-02-16
       | 12:09:29.565563802 -0800       +++ weird-1.c 2022-02-16
       | 12:09:38.185718722 -0800       @@ -7,6 +7,7 @@                int
       | x = 42;               +        int main(void)        {        #if
       | __LINE__ % 2 == 0
       | 
       | Explanation:                 {       #if __LINE__ % 2 == 0    //
       | If this line number is even         typedef int foo;       // foo
       | is a typedef name for int       #endif         foo(x);
       | return 0;       }
       | 
       | If foo is a typedef name for int, then "foo(x)" is syntactically
       | _declaration_. It 's declaring a local variable x to be of type
       | foo, alias for int.
       | 
       | If the typedef is missing, then foo(x) refers to the file-scope
       | identifiers: the function foo and variable x. It is a call to foo
       | passing the value 42 of x.
       | 
       | The preprocessor conditional could easily introduce a syntax
       | error, but the issue in Perl is that a parsing decision (how the
       | / token is lexically categorized) is made based on the compile-
       | time value assigned to f. This is similar to the compile-time
       | meaning of foo we are setting up with the presence or absence of
       | the typedef.
        
         | kazinator wrote:
         | With a small change to the weird-0 and weird-1 programs:
         | $ gcc -O2 -Wall -W weird-0.c       weird-0.c: In function
         | 'main':       weird-0.c:15:7: warning: unused variable 'x'
         | [-Wunused-variable]          foo(x);              ^
         | $ gcc -O2 -Wall -W weird-1.c       weird-1.c: In function
         | 'main':       weird-1.c:16:3: error: too few arguments to
         | function 'foo'          foo(x);          ^~~
         | weird-1.c:3:6: note: declared here        void foo(int x, int
         | y)             ^~~
         | 
         | The change is in the foo function:                 void foo(int
         | x, int y)        {          printf("foo(%d, %d)\n", x, y);
         | }
         | 
         | The call is now erroneous, and with the increased compiler
         | optimization level and diagnostics, the declaration case
         | diagnoses x being unuse
        
       | G3rn0ti wrote:
       | 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 divides the
       | result by 1 on fridays
       | 
       | # but on other days causes the interpreter to trigger a syntax
       | error because it expects
       | 
       | # f to take an argument list "(...)" but receives an operator
       | "/".
       | 
       | f/1;#/+
        
         | Sophira wrote:
         | This is generally correct, but your final analysis is slightly
         | wrong and this is a perfect example of why Perl can be
         | difficult to parse.
         | 
         | If you add a 1 to the end of the "f/1;#/+" line, so that it
         | becomes "f/1;#/+1", the code will become correct.
         | 
         | What's actually happening is that on Fridays, the "f/1;#/+"
         | line means "call f, divide the result by 1, and throw away the
         | result", followed by a comment. On any other day, it means
         | "call f with the regex parameter /1;#/ and add an unspecified
         | parameter to it". Since the right hand side of the + operator
         | isn't specified, it is syntactically incorrect.
        
         | hnu0847 wrote:
         | Why does the following expect arguments:                   :
         | sub {};
         | 
         | Don't all perl subroutines allow any number of arguments
         | (including 0) to be passed?
         | 
         | Does the fact that the above is an anonymous subroutine affect
         | the answer to my question?
        
           | jwilk wrote:
           | A sub without prototype (anonymous or not) indeed allows any
           | number of arguments. That's sufficient to trigger the syntax
           | error.
        
         | darrenf wrote:
         | > _# 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  <stuff>` tries to
         | compile `<stuff>` 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
        
           | Sophira wrote:
           | > 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.
           | 
           | Isn't that what the parent said, going by your quote? They
           | said "the following line [...] on fridays but on other days
           | causes the interpreter to trigger a syntax error".
        
             | darrenf wrote:
             | Yes! You're right. Not sure what happened to my brain
             | there. Too much staring at Perl, I suspect.
        
         | metalliqaz wrote:
         | Thank you for this. I hate trying to read Perl so much.
         | 
         | What is the "#/+" for?
        
           | jwilk wrote:
           | On Fridays, it's just a comment.
           | 
           | Otherwise, "f/1;#/+" is equivalent to something like:
           | f(/1;#/ +)
           | 
           | where /1;#/ is a regexp matching operator, and stray +
           | triggers syntax error.
        
           | mmaunder wrote:
           | Worked as a Perl dev for 15 years and enjoyed it. The hardest
           | thing was the number of ways to do OO Perl using Perl5.
           | Everyone has their own flavor. And TMTOWTDI was a motto the
           | community was proud of.
           | 
           | Having said that, nothing could touch mod_perl performance
           | under Apache in the late 90s. Massive web apps were built on
           | this including eToys dot com where I worked before it
           | imploded in the dot-com bust.
        
             | programd wrote:
             | > Worked as a Perl dev for 15 years and enjoyed it
             | 
             | Similar situation here. Perl is awsome and I'm still bitter
             | that Python won. I mean significant whitespace - what great
             | madness is this???
             | 
             | Anyway, yes, mod_perl ran the Web for about a decade in the
             | early 2000s and I built and maintained huge websites which
             | were all Perl on the back end.
             | 
             | BTW the book "Perl Best Practices" by Damian Conway [0] is
             | the best general programming book I have ever read. Every
             | software engineer should read it no matter what language
             | they program in. So much good advice which applies to
             | pretty much any significant software project. IMHO right up
             | there with the "Mythical Man Month", though obviously much
             | more low level.
             | 
             | [0] https://www.oreilly.com/library/view/perl-best-
             | practices/059...
        
             | tomc1985 wrote:
             | > Worked as a Perl dev for 15 years and enjoyed it. The
             | hardest thing was the number of ways to do OO Perl using
             | Perl5. Everyone has their own flavor. And TMTOWTDI was a
             | motto the community was proud of.
             | 
             | One of my frist dev jobs was slinging perl script, I loved
             | that attitude and it made for a fantastic learning
             | environment. I really dislike the feeling of having to
             | write code in a straightjacket because tHe TeAm CaN't
             | UnDeRsTaNd iT!!!
             | 
             | We minimized the negatives of TMTOWTDI by incorporating a
             | house style, but it was flexible because we were all smart
             | people whose minds didn't crash because we saw a statement
             | we didn't expect.
        
           | space_ghost wrote:
           | Flavor? "#" starts a comment, so the "/+" characters are
           | ignored by the interpreter.
        
           | [deleted]
        
           | G3rn0ti wrote:
           | > What is the "#/+" for?
           | 
           | I am sure this is not necessary for the behavior described.
           | It's just a comment.
           | 
           | BTW: I am working for a company still maintaining a large
           | Perl code base and I think this is rather obscure stuff. You
           | rarely need to run something at compile time, hack the symbol
           | table and you almost never need "sub() {}" to define
           | subroutines with an empty "prototype". If I saw this in a
           | code review I would most definitely had a closer look and
           | would decline a PR if that was unnecessary. Meta programming
           | should not be done lightheartedly and better serves a serious
           | purpose.
        
       | pvg wrote:
       | It's mentioned in the source but it's based on this:
       | 
       | https://www.perlmonks.org/index.pl?node_id=44722
        
       | jakub_g wrote:
       | Semi-related HN classic: "Openoffice can't print on Tuesdays"
       | https://news.ycombinator.com/item?id=8171956
       | 
       | A handful of curated weird stories like this:
       | https://500mile.email/
        
       | gfldex wrote:
       | As a sister language of Perl, Raku can do the same trick.
       | constant &s = (now.DateTime.day-of-week == 7) ?? sub () {} !! sub
       | (|) {};         constant c = s(42);
       | 
       | Constants are evaluated at compile time. Here we define a sub
       | that takes no argument or any number of arguments depending on
       | the day of the week (In Raku we start at 1 for monday to avoid
       | ending the universe by deviding by 0). While binding the return
       | value of s(42) to a constant we force execution of that sub at
       | compile time. Thusly, we create a program that can not be
       | executed when compiled on sundays. This is reasonalbe, because by
       | heavenly mandate we are bound to rest on that day.
       | 
       | Modules are precompiled, programs are not (yet). So to make this
       | really depend on the day of compilation we have to put it into a
       | module (for now).
        
       | markstos wrote:
       | Just reading the headline gave me traumatic flashback to a
       | customer project for a winter sports brand that broke on April
       | 1st after not being modified for months prior to this.
       | 
       | You guessed it: There was a sleeper bug detonated by the date
       | change. Pain the butt to track down in Perl code that was
       | generating an Excel spreadsheet cell-by-cell.
        
       | bastardoperator wrote:
       | I worked with Randal L. Schwartz for several years in the Los
       | Angeles area. I was already doing Perl but getting an opportunity
       | to see his code and ask him questions was something that changed
       | my career for the better. Thanks Merlyn!
        
         | RandalSchwartz wrote:
         | Have you seen my "parse JSON in a single Perl Regex"?
         | https://www.perlmonks.org/?node_id=995856
        
       | Drblessing wrote:
       | What about Phase-Of-The-Moon code?
        
       | WesolyKubeczek wrote:
       | Why only things like these float up to the front page, and not
       | elegant and/or wholesome things written in Perl?
        
         | gerikson wrote:
         | Perl is like life - it contains both good and bad.
         | 
         | And good things in Perl don't get noticed because they Just
         | Work.
        
         | JohnHaugeland wrote:
         | possibly because no such thing exists
        
         | sundarurfriend wrote:
         | Because with its declining popularity, most people here are
         | unfamiliar with the language except for its meme status as
         | "that weird line noise language". Things that confirm pre-
         | existing beliefs are easy to accept and upvote, whereas good
         | Perl code would require (a) some actual thinking, and (b)
         | challenging the socially accepted narrative - both of which are
         | relatively much harder.
        
           | WesolyKubeczek wrote:
           | Good Perl code would also look pretty boring, almost like
           | enterprise Java.
           | 
           | I'd wager that all code that "just works", in any language,
           | looks bland and predictable.
           | 
           | But I'd rather have that than cute and clever any day.
        
             | anthk wrote:
             | Good Perl looks like a mix between structured SH and a
             | dumbed down C with no pointers. Boring, as you say. But it
             | works.
        
           | kqr wrote:
           | Afaik Perl is not declining in popularity, it's just not
           | growing in popularity as fast as many other languages, so
           | it's market share shrinks while the number of users it has
           | grows.
        
           | anthk wrote:
           | True, most Gen-Z ers know nil.
           | 
           | First they should try Perl as if it was a tuned up AWK, and
           | then, read the Orelly Perl books as if they were a religion.
           | 
           | https://docstore.mik.ua/orelly/perl4/index.htm
        
         | layer8 wrote:
         | Right, it's elegant Perl that would be newsworthy, not gruesome
         | Perl.
         | 
         | (Tongue-in-cheek, I'm actually rather partial to Perl.)
        
         | lanstin wrote:
         | I loathe perl still (based on having to SSH (or telnet?) into
         | people's systems and debug their perl scripts in the 90s) but,
         | Higher Order Perl, https://hop.perl.plover.com/ is a truly
         | excellent introduction to the power of functions that generate
         | functions, more accessible and more immediately useful than
         | Paul Graham's On Lisp. The lessons are immediately applicable
         | at least to Javascript and Python. Strongly typed things like
         | Go make it a bit more work, but still you'll understand why the
         | work is worth doing.
        
       | alkaloid wrote:
       | Someone found my telco code.
        
       | fouronnes3 wrote:
       | Pro tip: add test cases to your CI runs with modified system
       | date.
        
         | WesolyKubeczek wrote:
         | 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 raise and talked shit to him? Too many
         | possibilities. And your timebomb might be in one of your
         | dependencies to boot.
        
           | zanderwohl wrote:
           | 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/fcda9bbdff88d45cc90
           | 61606b4b...
        
         | JohnBooty wrote:
         | Amen.
         | 
         | Worked for a few years at a company with a medium-sized
         | codebase whose tests only worked before 6PM.
         | 
         | (Run the tests later than that, and you wind up with some
         | timeframes that span calendar days and therefore break things.
         | Was the underlying code broken, or the tests, or both? Who
         | knows!!)
         | 
         | Was never allowed to fix and investigate. Or to be specific, we
         | were never given the time to fix it. Management simply didn't
         | see it as a problem.
         | 
         | In my younger days I would have gone all HERO HACKER and fixed
         | it anyway on my own time. But now, I know how that turns out.
         | You waste a bunch of evenings fixing it, and usually introduce
         | some other regressions, and you get zero glory and lots of
         | blame. Best case scenario is no regressions and zero glory.
         | 
         | So, screw it. Old-and-jaded me never lifted a finger. If the
         | company doesn't care, why should I?
         | 
         | But, that is an excellent protip. If you are working on a team
         | that actually values things that work. Time/date dependent code
         | is _very_ tricky to get right, especially when multiple time
         | zones are involved. If your test suite doesn 't cover multiple
         | possibilities, your code is nearly guaranteed to be wrong.
         | 
         | It's not even like you have to write brand-new, cleverer tests.
         | Just "brute-force" it, assuming your tests are performant:
         | 
         | before:                   some_tests
         | 
         | after:                   [time_zone_1, time_zone_2,
         | time_zone_3].each do |tz|            [time_of_day1,
         | time_of_day2, time_of_day3].each do |tod|
         | some_tests(tz, tod)            end         end
         | 
         | ...that kind of thing. That's what I did when I wrote new code
         | at that company, even though I refused to fix the legacy stuff.
         | My tests were faster, too. Almost like I knew what I was
         | doing...
        
           | janekm wrote:
           | Was it a German company? If so "you can only do work during
           | working hours" would be considered a feature not a bug ;)
        
       | [deleted]
        
       | raxxorrax wrote:
       | I have written code that only works in winter because of daylight
       | saving times and some unfortunate date conversions, but having a
       | temporary correct syntax is really a new high.
        
         | profmonocle wrote:
         | The first iPhone app I wrote back in college would crash if you
         | used it in a time zone with a positive UTC offset. I can't even
         | remember why.
        
         | nicoburns wrote:
         | > I have written code that only works in winter because of
         | daylight saving times and some unfortunate date conversions
         | 
         | Not sure where you are located, but this can be particularly
         | bad in the UK where winter time happens to coincide with UTC.
        
           | DocTomoe wrote:
           | Let's be pedantic about this, because this is one of the very
           | few areas where pedantry matters: GMT ("British Winter Time")
           | is NOT UTC, and it can differ from UTC up to 0.9 seconds. GMT
           | is a time zone (corresponding to UT1). UTC is a time
           | standard.
        
             | dane-pgp wrote:
             | I appreciate your pedantry, and I wonder if you know of a
             | widely used computer system which genuinely implements the
             | GMT time zone as something different from UTC+0.
             | 
             | There may be some niche astronomical or legal(?)
             | applications which have to keep track of the potential 0.9
             | seconds skew, but my impression is that any app which
             | claims to support a "GMT" (or Europe/London) option is
             | actually only supporting "GMT-ish".
        
             | Dylan16807 wrote:
             | > GMT is a time zone (corresponding to UT1)
             | 
             | Are you sure? Looking into things I would have said that
             | GMT exists as a time reference but all the time _zones_ are
             | based on UTC.
        
             | jfk13 wrote:
             | To be pedantic, this is an area where pedantry
             | _occasionally_ matters. For the vast majority of (casual)
             | usage, it doesn 't.
        
               | gerikson wrote:
               | Indeed. I get invites from people from the UK who simply
               | refer to the current local time (GMT or BST) as "GMT". It
               | just means current London time to them.
        
               | ycombobreaker wrote:
               | Same happens in the US, people use EST/EDT
               | interchangeably (and incorrectly) when they mean Eastern
               | timezone. Or Central/Mountain/Pacific.
        
             | nicoburns wrote:
             | Ok, fair enough. But it's close enough that it's very easy
             | for anything that isn't working with second-level
             | granularity to seem like they're working only to break as
             | soon as the time switches BST.
        
           | hughrr wrote:
           | Yeah it's horrible. I had a contract a number of years ago to
           | fix a bug that they had been fighting for 5 years. When
           | winter time kicked in all appointments on their booking
           | system collapsed to zero minutes long.
           | 
           | To fix this they ran a SQL script that changed the end date
           | on the DST switch over but that had some poor assumptions in
           | it and made it worse.
           | 
           | It also had to be correct in the past and the future.
           | 
           | I just rewrote the whole fucking thing from scratch.
        
         | hyperman1 wrote:
         | As a part of a release always got borked, I wrote a small bash
         | script that took currently deployed files, archived them to
         | rollback_dateandtime.tgz, then put the freshly released files
         | in its place.
         | 
         | It turns out we never did a release before 10:00, because it
         | ran fine for a few years, but the regex constructing the
         | filename could not deal with hours consisting of 1 number.
         | 
         | Oh well, never write production shell scripts while your
         | platform is burning.
         | 
         | The fix is literally 1 character, but I only get access when
         | production burns. So I was not allowed to change it and the
         | owner does not want to implement it and file all release
         | paperwork it entails. Instead, mgmt forbid this type of release
         | before 10:00.
        
           | gpvos wrote:
           | This is why we can't have nice things.
        
         | chaosite wrote:
         | I have written code (at work) that crashes when the moon is in
         | a specific phase.
         | 
         | I had a "switch(moon_phase)" and forgot one of the cases... And
         | the Android app was in debug mode, so any uncaught exception
         | brought the whole thing down.
        
           | grishka wrote:
           | Not nearly as cursed as two parent comments, but there was a
           | widespread problem in my very popular Android app. The
           | relative date formatting function worked incorrectly for many
           | users, it was off by one hour. It turns out that when Russia
           | (where most of our users were) had abolished DST, and then
           | changed timezones a couple of times, people got really
           | confused. Since Android's timezone data is part of the
           | system, it was basically set in stone. Most of the users
           | didn't choose the timezone with the correct offset, but
           | instead set their time an hour forward so the incorrect
           | timezone and incorrect unixtime cancel each other out for a
           | "correct" displayed time.
           | 
           | I ended up getting the known correct unixtime from the server
           | to try to guess which timezone offset the user _actually_
           | meant and correcting the result of System.currentTimeMillis()
           | and my formatting for that.
        
           | tupac_speedrap wrote:
           | Having the code crash every full moon would be pretty cursed
           | tbh.
        
         | dotancohen wrote:
         | I have once heard of some software that would crash on some
         | Wednesdays. Apparently Wednesday is the longest day name, and
         | it was overflowing some buffer. But only if the day of the
         | month was 10 or above, because the strings 1-9 still fit in the
         | buffer.
        
       ___________________________________________________________________
       (page generated 2022-02-16 23:00 UTC)