Posts: 2,169
Threads: 222
Joined: Apr 2022
Reputation:
103
Building this as an addition to Sam-Clip
Code: (Select All) FOR i = 1 TO 50
REDIM _PRESERVE c$(i)
c$(i) = LTRIM$(STR$(i))
NEXT
WIDTH 80, 25
idx = -1: GOSUB dsp
DO
_LIMIT 60
WHILE _MOUSEINPUT
mw = mw + _MOUSEWHEEL
WEND
IF mw <> oldmw THEN
adj = SGN(mw - oldmw): mw = 0
IF idx > 0 AND adj < 0 OR idx <= UBOUND(c$) - (_HEIGHT - 1) AND adj > 0 THEN GOSUB dsp
END IF
oldmw = mw
LOOP
dsp:
CLS
IF idx < 0 THEN
idx = UBOUND(c$) - (_HEIGHT - 2)
IF idx <= 1 THEN idx = 0
ELSE
idx = idx + adj
END IF
LOCATE 1, 1
i = idx: j = 0
DO
i = i + 1
j = j + 1: LOCATE j, 1
PRINT c$(i)
LOOP UNTIL CSRLIN = _HEIGHT - 1 OR i = UBOUND(c$)
RETURN
Pete
Posts: 229
Threads: 25
Joined: Aug 2022
Reputation:
23
The scrolling works great. I have a programming question regarding the use of GOSUB.
I tried changing this to SUB dsp and then changing the subroutine to SUB and END SUB. Then I realized this created a problem with the redim c$. Now it would have needed to be shared, and then the whole program might have to be very different.
Anyway, would you say using GOSUB is normally a better choice than SUB? I've been staying away from GOTO and GOSUB so I found this interesting.
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
If you're more comfortable writing subprograms then don't change that. Using "GOSUB" and "RETURN" isn't a great advantage by this time especially if you expect your BASIC code compatible with Freebasic or Purebasic. For example, for Freebasic you only need to change function name on LHS and equals to "RETURN", that's why "GOSUB" was eventually dumped by them to follow along with Visual Basic.
Coding while relying on "GOSUB" sections of code must have global variables always. If you're not used to it, it's going to be a mess trying to force that issue with "SUB... END SUB" and "FUNCTION... END FUNCTION" while they weren't designed for that purpose. If you need a local variable that has to keep its value after the subprogram is in must leave, and then come back, use "STATIC" to declare it instead of "DIM". In fact the whole subprogram could be declared "STATIC" (use keyword at the end after parameter list). But probably you knew this already.
Posts: 229
Threads: 25
Joined: Aug 2022
Reputation:
23
(11-12-2022, 04:24 AM)mnrvovrfc Wrote: If you're more comfortable writing subprograms then don't change that. Using "GOSUB" and "RETURN" isn't a great advantage by this time especially if you expect your BASIC code compatible with Freebasic or Purebasic. For example, for Freebasic you only need to change function name on LHS and equals to "RETURN", that's why "GOSUB" was eventually dumped by them to follow along with Visual Basic.
Coding while relying on "GOSUB" sections of code must have global variables always. If you're not used to it, it's going to be a mess trying to force that issue with "SUB... END SUB" and "FUNCTION... END FUNCTION" while they weren't designed for that purpose. If you need a local variable that has to keep its value after the subprogram is in must leave, and then come back, use "STATIC" to declare it instead of "DIM". In fact the whole subprogram could be declared "STATIC" (use keyword at the end after parameter list). But probably you knew this already.
I haven't used STATIC yet. I don't think my programming is very sophisticated, so I usually just DIM SHARED most of the time. I found that to be much easier than passing variables to sub programs and keeping track of that. I assume that STATIC would be similar to CONST? I checked the wiki and it says it's for retaining values, but I don't know what the difference would be (STATIC vs CONST)
I'm comfortable using SUB / END SUB for sure, just wondered if GOSUB might be an advantage sometimes, as it seems that was the case in this example.
Posts: 2,169
Threads: 222
Joined: Apr 2022
Reputation:
103
For solo programming, I say do whatever works best. For team projects, I would use SUBS and FUNCTIONS. Why? Productivity. Individuals are almost always more productive doing things in the coding style they like. Teams, on the other hand, benefit from consistency and management by bringing different SUBS and FUNCTIONS together to work correctly with the MAIN. Usually team members are assigned a task, which is relegated to a particular SUB or FUNCTION. All the team developers have to do is make their variables, required by the main and other SUBS and FUNCTIONS, documented so they can be passed by either reference or value. For passing variables, I'd say the best approach is to use TYPE variables as much as possible. (Note arrays cannot be passed as TYPE variables.) Anyway, TYPE variables allow for several variables of a TYPE to be passed by TYPE, instead of each variable needing to be added to the list of parameters. Another way is to just make all variables COMMON SHARED or SHARED. The drawback is naming in that you must make sure you don't use a SHARED variable name you do not intend to be passed to another SUB or FUNCTION. Again, using TYPE variables help here, as well.
AS for GOSUB and GOTO, two different animals, really. GOTO is almost like a patch keyword. Forgot something in an almost completed program? Patch it with GOTO and a label instead of redoing the code. To use GOTO as a coding practice makes debugging code very difficult. Hence the nickname, spaghetti code. In a few instance though, GOTO is the most optimized way of achieving the proper flow. We have a keyword, _CONTINUE, which allows users to skip stuff in a loop, which would be like coding the label, "SkipHere:" above the LOOP statement then putting a GOTO SkipHere, where needed, in the loop. GOSUB, on the other hand, is like having the power of a SUB without having to pass variables. It always returns to the point it was called, so it is easy to debug, especially if you don't get into nesting. (Nesting is putting more GOSUB statements in a GOSUB statement. Anyway, nesting aside, GOSUB is a code saver when you need to call the same procedure more than one time. GOSUB can also help you visualize your program flow better, because instead of wading through many non-descriptive lines, you go from one well named procedure like GOSUB accounting: GOSUB display: GOSUB UserInput.
Pete
Shoot first and shoot people who ask questions, later.
Posts: 2,169
Threads: 222
Joined: Apr 2022
Reputation:
103
(11-12-2022, 04:38 AM)james2464 Wrote: I haven't used STATIC yet. I don't think my programming is very sophisticated, so I usually just DIM SHARED most of the time. I found that to be much easier than passing variables to sub programs and keeping track of that. I assume that STATIC would be similar to CONST? I checked the wiki and it says it's for retaining values, but I don't know what the difference would be (STATIC vs CONST)
I'm comfortable using SUB / END SUB for sure, just wondered if GOSUB might be an advantage sometimes, as it seems that was the case in this example.
STATIC is a bit like a local CONSTANT. That means it remains in the SUB. Let's say you are counting something with the variable cnt, but it isn't shared or passed. by declaring it as a STATIC variable, you can come back to the counting SUB and pick right up where you left off. If you didn't either pass the cnt variable, or declare it as SHARED or STATIC, cnt would be zeroed the next time the counting SUB call was made.
Code: (Select All) SUB mySUB
STATIC cnt
Pete
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
https://qb64phoenix.com/qb64wiki/index.php/FILES
Check out the example on the rewritten "DIR$()". It has a good example of "STATIC" to signal when the first time a subprogram is called, to give some values to the variables only at that point and not at the second or further times the same subprogram is called. A variable declared "STATIC" inside a subprogram really is a global variable but is not accessible to the "main program" or other modules that might be connected but kept separately from the "main program."
"DIM SHARED" is the only way supported in Freebasic to allow subprograms to look at arrays without needing to use clunky pointers to pass them as parameters. "SHARED" inside a subprogram isn't allowed there; QB64(PE) allows it but it's considered bad practice to rely on it. The other programming system has OOP concepts (code and data security of a running program) which means "SHARED" has no place in it.
Don't be confused by my having to mention a programming system other than QB64(PE); it's my attempt to explain how fortunate we really are to be able to do things that we've learned with Q(uick)BASIC or GW-BASIC or some other dialect. However, from GW-BASIC/BASICA to QuickBASIC/QBasic things became different indeed with needing to split code into modules and scopes, and Visual Basic went even further.
Posts: 229
Threads: 25
Joined: Aug 2022
Reputation:
23
Great explanations, thank you! I understand the convenience of GOSUB for sure. A little less formal than SUB, although I enjoy the way QB64 makes your sub name into a new command. But I can also see that being less clear when following/reading your program.
STATIC makes sense now...much appreciated.
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
Pete, it's a good thing you're building your "Sam Clip" for Windows only because this would never work toward a web browser. Tried using "_CLIPBOARD$" in a program I compiled to paste into some text field inside a page displayed by Brave browser but the idiot program hung up until I closed my program! It pasted nothing. I haven't tried this with Firefox and an OS different from Manjaro MATE.
The issue might be which text field the attempt is made to paste, eg. forum password. Not like the blank I used to type in this message. I understand why but I got irritated when the browser locked up instead of ignoring clipboard paste keystroke.
Posts: 476
Threads: 25
Joined: Nov 2022
Reputation:
45
(11-12-2022, 03:52 AM)Pete Wrote: Building this as an addition to Sam-Clip
Code: (Select All) ---8<---
IF mw <> oldmw THEN
adj = SGN(mw - oldmw): mw = 0
That right there is clever. Throw away the delta, only care about distance, right?
Thanks for sharing this example.
|