|
Post by B+ on May 12, 2020 15:26:07 GMT
For the first: "vName$" and "vValue" exist before calling the sub; it suffices to give the variables processed in the gosub the values before its call (same for the functions). The case for which it is impossible is when the sub calls itself with different parameters (I tried without success) EDIT: But maybe with two separate gosub. Are you talking about a recursive GOSUB? Here is example comparing the fac(n) function and the [factorial] GOSUB: 'test recursive factorial function versus recursive [factorial] GOSUB that modifies variables n and factorial
print "The Function way:" n = 5 print "factorial of ";n;" is ";fac(n);" and n is still ";n;" according to the fac(n) function." 'recursive function fac print
print "Here is the GOSUB way (= high maintenance):" factorial = 1 '<<< initialize the return variable for the "function" GOSUB n = 5 ' <<< initialize the start n gosub [factorial] print "The factorial variable is at ";factorial;" but n is now at ";n;" from using GOSUB [factorial] recursively." end
[factorial] if n = 1 then return else factorial = factorial * n : n = n - 1 : gosub [factorial] return
function fac(n) if n <> 1 then fac = n * fac(n - 1) else fac = 1 end function
|
|
|
Post by honkytonk on May 12, 2020 16:03:08 GMT
Can we replace the sub with two interconnected gosubs or other ways in this code ?
'permutations for JB v1.01 [B+=MGA] 2017-02-17 'recursive ordered permutations 'if 1st element < 2nd element < 3rd element... then list acsends ' modify ordered permutaions to handle words in string wordList$ = "cat dog fox rat bee" s$=wordList$ gosub [wcnt]: wc=wcnt if wc > 9 then print "Too many words, bye!" : end n=wc: gosub [factor] dim p$(factor+1) s$ = mid$("123456789", 1, wc) global ls, index ls = len(s$) : index = 0 dim c$(ls) n=wc call orderperm s$ 'load perms p$() for i = 1 to factor scan nn=nn+1: pp$="" for j = 1 to ls scan pp$=pp$+word$(wordList$, val(mid$(p$(i),j,1)));" " next print nn;" ";pp$ next sub orderperm r$ scan if len(r$) = 0 then index = index + 1 for i = 1 to ls b$ = b$ + c$(i) next p$(index) = b$ else lr = len(r$) for i = 1 to lr c$(ls - lr + 1) = mid$(r$, i, 1) r1$ = mid$(r$, 1, i - 1) + mid$(r$, i + 1) call orderperm r1$ next end if end sub [wcnt] do cnt = cnt + 1 loop until word$(s$, cnt) = "" wcnt = cnt - 1 return [factor] f = 1 for i = 2 to n f = f * i next factor = f return
|
|
|
Post by B+ on May 12, 2020 16:27:05 GMT
Hmm... looks like the i's in one GOSUB will interfere with the i's in another call to GOSUB because they are on same level of scope.
How to make them unique in each GOSUB call? that's a thinker ;-))
Maybe saveI = i before GOSUB and i = saveI after GOSUB? same with all other variables on same scope that get changed as GOSUB progresses.
Like I said, GOSUB way is possible but much higher maintenance is involved because the scope levels are not independent as the are in real SUB or FUNCTION.
Nope the saveI's will change each other as well, need to track levels of GOSUB and array the variables to the level they are on.
Can you do for i(level) = 1 to n ? probably not.
SUBs win! ;-))
|
|
|
Post by B+ on May 12, 2020 16:44:43 GMT
Well FOR loops are out but WHILE... WEND loops might work:
dim i(100) x = 10 : n = 6 i(x) = 1 while i(x) <= n 'For i(level) = 1 to 6 print i(x), i(x) * 2 i(x) = i(x) + 1 wend
Yeah so DIM arrays for every variable in GOSUB to max amount of calls to the GOSUB from itself.
But really isn't SUB easier?
|
|
|
Post by honkytonk on May 12, 2020 16:57:51 GMT
Since the sub wins .. How to go to a gosub when we are in a sub (not self-calling), or get out of a sub and re-enter it where you left; because this is the real problem?
|
|
|
Post by B+ on May 12, 2020 17:27:26 GMT
Since the sub wins .. How to go to a gosub when we are in a sub (not self-calling), or get out of a sub and re-enter it where you left; because this is the real problem? A procedure (a SUB or FUNCTION) is supposed to be completely self contained to do one job and then return to code block that called it. You can use a GOSUB inside a procedure and all the variables would remain on same scope level as the procedure. Even if you could GOSUB outside a procedure it is very bad idea because of variable scoping. I have no idea why you would exit a procedure before it did it's job nor why you'd try to re-enter a procedure "where you left". But here's is another advantage of procedures, you can call other procedures (not GOSUBs) while inside them to help finish the job the caller is tasked to do, very dangerous to call GOSUBs from other GOSUBs because of the intermix of variables on the same level. When you leave a procedure (not a GOSUB) all the variables are erased, temporary helpers until the task is done, not so with GOSUBs. It is a paradigm shift to go from working with GOSUBs to procedures and takes a new practice in thinking but well worth the effort.
|
|
|
Post by Rod on May 12, 2020 17:37:09 GMT
honkytonk, you are overthinking it Subs and Functions are very useful and the whole world uses them. At this time you don't "like" them but that is probably because you are not yet understanding their benefit.
You should never even think about [gosub] out a Sub or Function. The whole point is that they are self contained, pass in the parameters they need, pass out the result you want. Inside that completely self contained code block you can use whatever variable names you like safe in the knowledge that they are all unique to the Sub or Function.
As said before they are only code blocks which get called in a special way.
This business of going out and reentering is in any event bad thinking. A code block should run to completion and jump at the end or await the next user action.
|
|
|
Post by honkytonk on May 12, 2020 22:43:27 GMT
I understand the advantages of subs and functions; but it is a shame to have to abandon the gosub when we put a sub somewhere, I have the feeling of becoming a prisoner of the system. (No doubt am I an old anachist?)
|
|
|
Post by B+ on May 13, 2020 0:35:54 GMT
I understand the advantages of subs and functions; but it is a shame to have to abandon the gosub when we put a sub somewhere, I have the feeling of becoming a prisoner of the system. (No doubt am I an old anachist?) Man you need to make a couple of SUBs and FUNCTIONs of your own, ones that might be handy in any program, then you will get it! How about a SUB that will find every instance of something in a String and replace it with something else (including "", nothing). This comes up often including the start of this thread! Or maybe it is a Function that you return the revised string like myNewString$ = FunctionName$(oldString$, replaceMe$, withReplace$) 1. Think of a name ie replace$ 2. Think of the parameters needed to do its job: the string to work on strng$, the item to replace replaceMe$, the replacement replaceStr$ 3. Think only the code needed to transform the string with the substitutions: could use WORD$ or INSTR to find the items to replace. 4. Build a little tester app to work out the bugs. Try to think up items that will bust your new procedure like what if some of the arguments are "" nothing? That's basically how I do it.
|
|
|
Post by Rod on May 13, 2020 6:00:28 GMT
We have not abandoned GOSUB it’s just called another name, CALL SUB or FUNCTION, and to play the game you pass parameters when you gosub in this way.
|
|
|
Post by honkytonk on May 13, 2020 8:53:11 GMT
Yes, I see that I will have to submit to subs but it makes the program difficult to modify, and less readable; although that dispenses with the mastery of the variables; what I find is a bad habit that can play nasty tricks elsewhere. So no more gosub go to subs. OK. Thank you for the convincing preaching.
|
|
|
Post by Rod on May 13, 2020 13:26:16 GMT
Ha, you don't fool me. Your not convinced Good naming convention helps readability. But you code how you like and what you like and enjoy.
|
|
|
Post by honkytonk on May 13, 2020 14:57:29 GMT
Should I conclude that we cannot replace a sub that calls itself with something else?
|
|
|
Post by B+ on May 13, 2020 15:05:51 GMT
Yeah GOSUBs are fine, a step towards full fledged SUBs and are appropriate for one-off app code or even inside a procedure.
Procedures are easy to port to different apps because their innards are independent of main code. Build a tool box of subs and functions that can be reused in other programs for common tasks like replacing words in a string as was needed at start of this thread.
|
|
|
Post by tsh73 on May 13, 2020 16:10:59 GMT
Indeed we cannot. Recursion works by using local variables for all called copies of SUB. GOSUB/RETURN have no local variables, at all.
|
|