Maximum Recursion Depth

Mathematica, 15 bytes

$RecursionLimit

¯\_(ツ)_/¯

Try it online!


Python 3, 40 bytes

def f(x=2):
 try:f(x+1)
 except:print(x)

Try it online!

Without just reading it from the builtin. We start at 2 instead of 1 because the except clause is run one level before it errors. This is a byte shorter in python 2, of course.


JavaScript (Babel), 35 33 29 bytes

f=_=>do{try{-~f()}catch(e){}}
  • 2 bytes saved thanks to Neil.

Try it here, or use the Snippet below to test it with eval instead of do.

console.log((f=_=>eval(`try{-~f()}catch(e){}`))())


Japt port, 24 bytes

It's not really worth posting this as a separate solution as it's, essentially, identical.

Ox`try\{-~rp()}¯t®(e)\{}

Test it


Explanation

JavaScript itself doesn't have a recursion limit per se, rather the limit is imposed by the interpreter (i.e., the browser) - good thing we define languages by their interpreter 'round here! Among other factors, the limit can vary by browser and available memory, which is impacted by the operations being performed. The following Snippet illustrates that last point, using the 5 different versions of this solution I went through. As you can see from the last 2 tests, in Chrome, at least, even the order of operations can make a difference.

console.log((f=(i=0)=>eval(`try{f(i+1)}catch(e){i}`))())
console.log((f=i=>eval(`try{f(-~i)}catch(e){i}`))())
console.log((f=(i=0)=>eval(`try{f(++i)}catch(e){i}`))())
console.log((f=_=>eval(`try{-~f()}catch(e){}`))())
console.log((f=_=>eval(`try{f()+1}catch(e){0}`))())
console.log((f=_=>eval(`try{1+f()}catch(e){0}`))())

Given that, we therefore don't have the convenience of a constant or method to work with. Instead, we're going to create a function that calls itself continuously before, eventually, crapping out. In it's simplest form that is:

f=_=>f()

But that's not much use to us for this challenge as it only throws an overflow error with no indication of how many times f called itself. We can avoid the error by trying to call f continuously and catching when it fails:

f=_=>{try{f()}catch(e){}}

No error, but still no return value of how many times the function managed to call itself before failing, because the catch isn't actually doing anything. Let's try evaluating the try / catch statement:

f=_=>eval(`try{f()}catch(e){}`)

Now we've got a value being returned (and, because this is code golf, saved ourselves a few bytes over using an actual return). The value being returned, though, is undefined, again because the catch isn't doing anything. Luckily for us -~undefined==1 and -~n==n+1 so, by popping a -~ in front of the call to f, we've essentially got -~-~ ... -~-~undefined, with another -~ prepended with each call, giving us the number of times f was called.

f=_=>eval(`try{-~f()}catch(e){}`)

Tags:

Code Golf