Author Topic: for/next fundamental flaw  (Read 3315 times)

0 Members and 1 Guest are viewing this topic.

Brian Alvarez

  • Guest
for/next fundamental flaw
« on: July 15, 2019, 08:53:37 PM »
Charles, i found a problem with for/next that i believe you will want it addressed asap.
Take a look at this for/next block:

Code: [Select]
        for i = 1 to 3 Step forSTEP()
            print i       
        next i

The STEP is this function:

Code: [Select]
FUNCTION FORSTEP() AS INT
    STATIC INT s
    s += 1
    RETURN s
END FUNCTION

STEP should only be consulted/invoked once, and the for/next should rely on resulting step of that one invokation,
however, the step is being consulted on each iteration, resulting in one incomplete loop. This could also cause
an endless loop under some circumstances.

 This is how it should be for C++ style FOR/NEXT blocks, but not for BASIC. I discovered this making tests
in my for/next blocks (they work great now BTW), and i believe this also applies to the TO variable (3 in this case).

 There is no problem when STEP is a literal number or a variable, but for functions that may return a different value on
every invokation, this is going to be a problem at some point.

Edit:
 While on it, maybe it is also worth to take a look at why when jumping (using goto) into a c++ style for/next block
it works fine but for BASIC mode for/next blocks it aborts regardless of the for/next conditions?
« Last Edit: July 15, 2019, 09:30:37 PM by Brian Alvarez »

Aurel

  • Guest
Re: for/next fundamental flaw
« Reply #1 on: July 16, 2019, 03:32:22 AM »
This is not normal way  :o
i think this is:

Code: [Select]
   'for_step   .................
#lookahead
int i,fs

'proper way..................
fs=forSTEP()

 for i = 1 to 3 Step forSTEP()
            print i       
        next i

'printed in msgBox 1 , 3 OK!

'Code: [Select]

FUNCTION FORSTEP() AS INT
    STATIC INT s
    s += 1
    RETURN s
END FUNCTION

Mike Lobanovsky

  • Guest
Re: for/next fundamental flaw
« Reply #2 on: July 16, 2019, 10:09:09 AM »
Gentlemen,

According to the ECMA-116/1986 BASIC Standard, there may not be any forSTEP() fiddling with the increment value once the FOR statement initialization is done. At least, it should not affect the initial settings of the frame even if feasible in a particular BASIC dialect at all.

Consider the abstract from the Standard appended below.

Hitting the line that contains the FOR statement is the same as executing the first three LET statements that precede the equivalent DO/LOOP code. Once inside the original loop past the FOR statement line, the three initial equivalent LET statements are however not accessible any more. The original NEXT statement loops the code flow to the last equivalent LET statement inside the equivalent DO/LOOP block that can only control the iterator value but can't affect the own1 (limit) and/or own2 (increment) variables which are the interpreter/compiler intrinsics inaccessible to the programmer directly.

Deviation from the above scheme should be considered contrary to the expected BASIC code flow behavior and fraught with serious consequences.

Brian Alvarez

  • Guest
Re: for/next fundamental flaw
« Reply #3 on: July 16, 2019, 11:29:12 AM »
 Aurel, Mike, That is what i said. Once the STEP has been set, it should not be re-computed.

Charles Pegge

  • Guest
Re: for/next fundamental flaw
« Reply #4 on: July 16, 2019, 11:45:45 AM »
The iteration to expression is already precalculated, and I can do the same for the step expression.

Jumping into the middle of a Basic-style iteration bypasses the precalculations, which are done immediately before entering the loop.

I'll fix the goto problem you saw, Brian, though I seriously wonder whether I am doing a disservice to programming by providing this ability to jump into the middle of blocks. It also creates significant additional complexity in the linker. I would like to see if there are any well-structured uses for it. If not, I will withdraw it.

Brian Alvarez

  • Guest
Re: for/next fundamental flaw
« Reply #5 on: July 16, 2019, 01:03:08 PM »
...I seriously wonder whether I am doing a disservice to programming by providing this ability to jump into the middle of blocks. It also creates significant additional complexity in the linker. I would like to see if there are any well-structured uses for it. If not, I will withdraw it.

 As i mentioned, no need to "fix" the jumping into for/next. It is already working fine on this side, the backwards goto provided this ability, allowing compatibility with legacy PB code.
« Last Edit: July 16, 2019, 01:14:48 PM by Brian Alvarez »

Mike Lobanovsky

  • Guest
Re: for/next fundamental flaw
« Reply #6 on: July 16, 2019, 11:52:09 PM »
Hi Charles,

IMHO disallowing jumps into/out of the loops would be too stringent a limitation. What should be absolutely restricted instead is the ability to set/modify the looping conditions to initiate iteration once inside via a jump bypassing the FOR statement.

I think it would be easy to implement. You should only ensure increment (a.k.a. STEP) is zeroed out at app start and on breaking/exiting the loop executed in a natural way, i.e. through FOR initialization. If on entering the loop body via a jump increment stays zero, the block code or its part following the jump target is executed in the normal way up to the end of the loop. Then increment is evaluated there and if it is zero which dissatisfies the normal looping conditions, the loop is broken and the code flow exits past NEXT in a usual way.

Thus, the code inside an uninitialized loop would be executed only once. The purpose of the loop is to iterate, not suppress or conditionally execute or not execute, the code that's inside it. Consequently, executing the code only once if the loop frame stays uninitialized as a result of bypassing it via a direct jump, seems reasonable and not contradictory to the purposes of either the code or the loop.

Similarly, jumping back out of the loop should also be possible, which would naturally lead to re-iteration of FOR statement possibly with some other parameters, as may be set forth in the first iterations, to the code to be executed in that second re-iteration of the entire FOR/NEXT loop.

Charles Pegge

  • Guest
Re: for/next fundamental flaw
« Reply #7 on: July 17, 2019, 03:03:35 AM »
Thanks Mike,

All o2 blocks are scoped, and normally, inner labels are invisible from the outside of the block. This makes it possible to jump out of a block from any position, but you can only enter a block at the top end. This is a fundamental design feature of o2, and the linker is able to dump references whenever a block closes. It's very efficient as well as promoting good encapsulation.

But a lot of extra code is required to retrofit global-labels which have to be protected from the linker's axe.

Although jumping into a basic for block is hopeless, I can see the case for multiple entry-points into a do block, maybe..

Mike Lobanovsky

  • Guest
Re: for/next fundamental flaw
« Reply #8 on: July 17, 2019, 05:22:37 AM »
Thanks for the feedback, Charles!

I can only comment that scopes smaller than a subprocedure aren't ECMA-compliant either, which leaves the BASIC user/developer with the only choice to #undef Oxygen's implementation of strongly scoped pseudo-BASIC looping constructs and re-implement, possibly via the O2 and/or assembly macros, their own versions of ECMA-compliant FOR's, DO's, REPEAT's, and WHILE's. That's probably what Brian's doing in his Oxygen-based PluriBASIC.

Charles Pegge

  • Guest
Re: for/next fundamental flaw
« Reply #9 on: July 17, 2019, 09:25:57 AM »
Mike,

I will subdue my zeal for micro-scoping, and remove it from Basic if do while select case for. Then regular labels can be used inside these blocks.

The internal labels used by the blocks will have to be depth-tagged instead of losing scope. This will be the focus for version 0.2.4.

Mike Lobanovsky

  • Guest
Re: for/next fundamental flaw
« Reply #10 on: July 17, 2019, 10:49:30 AM »
That's great news, Charles! I bet Brian's going to appreciate that sacrifice of yours to the fullest. :)

Thank you!

JRS

  • Guest
Re: for/next fundamental flaw
« Reply #11 on: July 17, 2019, 11:55:41 AM »
Here is how ScriptBasic does FOR. I wouldn't change one aspect of its functionality.

Code: Script BASIC
  1. a = 1
  2. b = 20
  3. c = 2
  4.  
  5. FOR i = a TO b STEP c
  6.   PRINT i,"\n"
  7.   IF i = 5 THEN
  8.     i = 10
  9.     b = 15
  10.     c = 1
  11.   END IF
  12. NEXT
  13.  


jrs@jrs-laptop:~/sb/examples/test$ scriba varfor.sb
1
3
5
11
12
13
14
15
jrs@jrs-laptop:~/sb/examples/test$

Brian Alvarez

  • Guest
Re: for/next fundamental flaw
« Reply #12 on: July 17, 2019, 12:00:00 PM »
I bet Brian's going to appreciate that sacrifice of yours to the fullest. :)

Indeed. I Know charles is working pretty hard and i appreciate that!

 Thanks Charles.

Brian Alvarez

  • Guest
Re: for/next fundamental flaw
« Reply #13 on: July 18, 2019, 03:16:22 PM »
 Hello Charles, i tested the update you uploaded yesterday, THANKS!

 Labels work much better, however, i couldn't test the STEP as function.

 This works fine, it prints to screen the numbers from 9 to 1:

Code: [Select]
int i = 0

for i = 9 to 1 Step -1
    print i       
next i

print "done."

This one only prints "done.":

Code: [Select]
function forSTEP() as long
    return -1
end function

int i = 0

for i = 9 to 1 Step forSTEP()       
    print i       
next i

print "done."

Same happens when STEP is a variable.
« Last Edit: July 18, 2019, 04:28:30 PM by Brian Alvarez »

Charles Pegge

  • Guest
Re: for/next fundamental flaw
« Reply #14 on: July 19, 2019, 03:40:15 AM »
Hi Brian,

The problem is that the step direction is fixed at compile-time. An explicit '-' negative sign sets the step direction.

This works:
Code: [Select]
int i = 0
int f(){return 2}

for i = 9 to 5 Step -f()
    print i       
next i

print "done." '9 7 5 done