Question: I try to get all files like scheme\_12.sql and scheme\_23\_analytics.sql from folder with bash and regex works in a strange way in terminal, doesn't return anything. Also checked in python re and some interactive regex sites. It works.

my command `ls | find . -type f -regex "\.\/scheme_[0-9]+_([a-zA-Z]+)?.sql"`

but command without optional sentence works `ls | find . -type f -regex "\.\/scheme_[0-9]+.sql"`

I have no idea why. Can you help me find a mistake?

Answer: 
Because `result` is being reinitialized to `[]` every time the function is called. You are not passing itself the previous `result`, so it gets reset. In the end, only the last iteration with the last index (`[5]`) is sent back.

What you can do is use a third argument, optional, that you can initialize to `[]`.

```js
function recursive(index,length, result=[]) {
  result.push(index);
  return (index < length) ? recursive(++index,length, result) : result;
}

console.log(recursive(1,5)); // [1,2,3,4,5]
```
The [answer](https://stackoverflow.com/a/69105341) from Jeremy Thille is great. It explains what's wrong, and gives a useful and understandable alternative. The code is clean and as it's tail-recursive, it can take advantage of tail-call optimization if that ever becomes widespread. There is a bug in it, though: presumably `recursive (10, 3)` should return an empty array. Here it will return `[10]`.

While we could easily fix that, let's look instead at an alternative which is logically simpler and which avoids the default parameter. (An [earlier answer](https://stackoverflow.com/a/63708667) explains some of the potential issues with default parameters. Please understand that they are still a useful and powerful technique, but they do have a downside.)

So here's an alternative version, both in modern syntax:

```js
const range = (from, to) =>
  from > to ? [] : [from, ... range (from + 1, to)]

```

and in an older style:

```js
function range (from, to) {
  if (from > to) {
    return []
  }
  return [from] .concat (range (from + 1, to))
}

```

In either version, we simply recur by creating a new array, starting with the `from` value, and then including all the values from the recursive call. We hit a base case when `from` is larger than `to` and we return an empty array.

There is a big possible eventual disadvantage to this. It's not tail-recursive. Functions in which any recursive call is immediately returned without further processing is called tail-recursive. There are some very useful optimizations on that JS engines can apply to tail-recursive functions to avoid overflowing the recursion stack.

We could make this tail-recursive by adding the default parameter or adding a wrapper function which passes that parameter to an internal recursive helper function. Either would be easy to do. However, [we can see](https://kangax.github.io/compat-table/es6/#test-proper_tail_calls_(tail_call_optimisation)) that it makes little difference in modern JS, since at the time of this answer almost no engines support proper tail calls, even though I believe doing so is still in the specification. So for now, we won't bother.

Here is this version in action:

```js
const range = (from, to) =>
  from > to ? [] : [from, ... range (from + 1, to)]

console .log (range (1, 5)) //=> [1, 2, 3, 4, 5]
console .log (range (4, 4)) //=> [4]
console .log (range (5, 1)) //=> []
```

```css
.as-console-wrapper {max-height: 100% !important; top: 0}
```