input: "racecar"
current input is "racecar"
when function is called, the return value is added to the call stack
|-----------------------|
| isPalindrome("aceca") |
|-----------------------|
move to the next recursion call
current input is "aceca"
when function is called, the return value is added to the call stack
|-----------------------|
| isPalindrome("cec") |
| isPalindrome("aceca") |
|-----------------------|
move to the next recursion call
current input is "cec"
when function is called, the return value is added to the call stack
|-----------------------|
| isPalindrome("e") |
| isPalindrome("cec") |
| isPalindrome("aceca") |
|-----------------------|
move to the next recursion call
current input is "e"
since return value for this has hit the base case,
it will start executing by poping the top stack frame from the call stack
return result: true
|-----------------------|
| true |
| isPalindrome("cec") |
| isPalindrome("aceca") |
|-----------------------|
return result: true
|-----------------------|
| |
| true |
| isPalindrome("aceca") |
|-----------------------|
return result: true
|-----------------------|
| |
| |
| true |
|-----------------------|
return result: true
|-----------------------|
| |
| |
| |
|-----------------------|