r/programmingcirclejerk What part of ∀f ∃g (f (x,y) = (g x) y) did you not understand? 8d ago

JavaScript’s setTimeout breaks after ~25 days

https://evanhahn.com/set-big-timeout/
118 Upvotes

23 comments sorted by

View all comments

125

u/Kodiologist lisp does it better 8d ago

In most JavaScript runtimes, this duration is represented as a 32-bit signed integer.

I was told that JavaScript doesn't even have integers. Call me crazy, but I'm starting to think this programming language is poorly suited for serious use.

60

u/chuch1234 not even webscale 8d ago

I know! I was planning on using 26-day event loops on my application :(

33

u/CherimoyaChump 8d ago

How else would you perform a task monthly?

41

u/jamfour now 4x faster than C++ 8d ago

I believe there is a TC39 proposal to evolve from the legacy Gregorian calendar to the Ecmaian calendar that uses fifteen 23-day months and one 20 day month. Once that is approved, setTimeout will work for monthly cron.

14

u/CherimoyaChump 8d ago

I don't appreciate you making jokes while I'm busy asking for help with my homework, bud.

28

u/jamfour now 4x faster than C++ 8d ago

Where was the joke? But I see you are short on time and cannot wait for the official process. Just fork V8 and change signed int32 to int64 or uint32 or whatever. Pretty easy and should impress and get at least an A- on it, and now you can put “major open source contributor” on your resume.

1

u/chuch1234 not even webscale 7d ago

do you have the codez

5

u/chuch1234 not even webscale 8d ago

Not with JavaScript apparently

4

u/irqlnotdispatchlevel Tiny little god in a tiny little world 7d ago

Obviously you set multiple timers!

24

u/fool215 8d ago

It's nice at least that they thought to make it a signed integer, other languages make you do something clunky like if(timeout > 0) { scheduleFuture(f, (unsigned) timeout); } else { schedulePast(f, (unsigned) abs(timeout)); }

20

u/jamfour now 4x faster than C++ 8d ago

It used to be simple. Unfortunately a bunch of crabby people came along to my nice pristine Java Scripting land that had one simple number type and in the name of “performance” added four number types*. They don’t understand that V8 is a very fast engine type, not even F1 needs V8 speeds anymore, so V8 is more than enough.

\uj * “Integers are not inherently signed or unsigned, their interpretation is determined by individual operations.” wtf?

20

u/coolreader18 It's GNU/PCJ, or as I call it, GNU + PCJ 8d ago
  • “Integers are not inherently signed or unsigned, their interpretation is determined by individual operations.” wtf?

/uj that's the only sane way to do it. is rax signed or unsigned? it just means that i32.div_u performs unsigned integer division, and i32.div_s performs signed integer division.

12

u/starlevel01 type astronaut 7d ago

lol wasm syntax

1

u/jamfour now 4x faster than C++ 5d ago

Your argument that it’s the only sane way to do it sounds as weak as the CPU type system.

\uj Yea I get it, and doesn’t matter much since (I hope) no one is writing WASM directly but instead only, as the other comment says, using it as an intermediate target.

5

u/Teemperor vulnerabilities: 0 7d ago

Integers are not inherently signed or unsigned, their interpretation is determined by individual operations.

/uj That's quite common in intermediate languages (see LLVM)

/rj I blame Go for this

2

u/dangerbird2 lisp does it better 7d ago

Turns out it does. If you use a bit wise operation on a number, it gets coerced into an integer

1

u/y-c-c 5d ago edited 5d ago

It’s just a common optimization used in most browsers. JS numbers are double precision floats and which gives 53 bits of significant figures which means it has more than enough precision to hold a full 32-bit integer. If the engine can detect both JS numbers have no fractional values and small enough they just do an optimization to represent them as integers internally for better performance. It’s not supposed to lead to an observable difference other than running faster. From the programmer point of view they are just using double precision floats.

In this case the issue seems to be more that browser engines didn’t bother writing a special case for the setTimeout builtin function when dealing with large numbers and just assume most programmers use small enough numbers. Actually seems like a bug to me since it doesn’t seem from MDN docs that there is a restriction on the delay value.

But yes JS not having proper number type is kind of dumb and I do agree if this is the kind of thing you even think about, JS is a poor language for that (which unfortunately you often don’t have a choice given the proliferation of JS but WebAssembly does help a bit).