h3rald / min

A small but practical concatenative programming language and shell
https://min-lang.org
MIT License
310 stars 23 forks source link

linrec bug #139

Closed ghost closed 3 years ago

ghost commented 3 years ago

The linear recursion maker linrec has wrongs:

0 (dup 5 >)("finished!" puts!) 'succ (dup puts!) linrec

This is what did i do and result are:

finished!
6
6
6
6
6
6

instead of:

finished!
0
1
2
3
4
5

It doesn't executes final quote at every conditional step. It executes final quote by total step of loop execution at the end of linrec loop. That is not good. It is a bug i think. One should fix.

h3rald commented 3 years ago

Uhm... are you sure??? This is the implementation:

def.symbol("linrec") do (i: In):
    let vals = i.expect("quot", "quot", "quot", "quot")
    var r2 = vals[0]
    var r1 = vals[1]
    var t = vals[2]
    var p = vals[3]
    proc linrec(i: In, p, t, r1, r2: var MinValue) =
      i.dequote(p)
      var check = i.pop
      if check.isBool and check.boolVal == true:
        i.dequote(t)
      else:
        i.dequote(r1)
        i.linrec(p, t, r1, r2)
        i.dequote(r2)
    i.linrec(p, t, r1, r2)

If you notice I am executing the 4th quotation (r2) at every recursion...

ghost commented 3 years ago

Uhm... are you sure??? This is the implementation:

def.symbol("linrec") do (i: In):
    let vals = i.expect("quot", "quot", "quot", "quot")
    var r2 = vals[0]
    var r1 = vals[1]
    var t = vals[2]
    var p = vals[3]
    proc linrec(i: In, p, t, r1, r2: var MinValue) =
      i.dequote(p)
      var check = i.pop
      if check.isBool and check.boolVal == true:
        i.dequote(t)
      else:
        i.dequote(r1)
        i.linrec(p, t, r1, r2)
        i.dequote(r2)
    i.linrec(p, t, r1, r2)

If you notice I am executing the 4th quotation (r2) at every recursion...

I looked and ... That proc is a recursive proc and maybe it breaks the code? Because nothing looks bad about your code.

$ 0 (dup 5 >)("finished!" puts!) 'succ (dup puts!) linrec
finished!
6
6
6
6
6
6
 6
$ 0 (dup 5 >)("finished!" puts!) 'succ (dup puts!) linrec
finished!
6
6
6
6
6
6
 6
$ 0 (dup 5 >)("finished!" puts!) 'succ (dup puts!) linrec
finished!
6
6
6
6
6
6
 6

I tried it again and again but nothing changed. This seems abnormal bug. Also it caused #138 problem. Your algorithm and proc's execution style isn't same.

You may look deep of core.

Here is your factorial example(what it does):

5 (dup 0 ==) ‘succ (dup pred) ’* linrec
5 dup pred...
5 4...
5 4 dup pred...
5 4 3...
5 4 3 dup pred...
5 4 3 2...
5 4 3 2 dup pred...
5 4 3 2 1...
5 4 3 2 1 dup pred...
5 4 3 2 1 0...
5 4 3 2 1 0 succ...
5 4 3 2 1 1...
5 4 3 2 1 1 * * * * *...
120

It runs final quote after the quit of loop by five-times(is how many times did the loop run) => This is the buggy part.

h3rald commented 3 years ago

I actually think this is the way it's supposed to run.

Let's see:

The thing is q4 gets executed at the end of every recursion, the problem is that the previous recursions actually complete once the last one finishes, in reverse order... its recursing every time before executing q4.

ghost commented 3 years ago

So we got it!