Awh thank you for explaining. I was thinking of adding new used parameters, but I see that your ____ variable place holder idea addresses that… so I could add a new (to-be-used) variable just before it or anywhere after it. Some of my functions use WAY too many variables to include them all in a 2000 character command line, but the theory does seem solid, and the ____ variable you mentioned should really work in practice.
And as for the documentation you described, I do understand now and that’s exactly how I document my parameters… after some time the documentation fails to be maintained and grows out-dated, but some doc is better than no doc J.
I’ll have to start adding all my local variables to my def statements now, so that my functions can be recursion ready.
Thanks,
-john
From: br_forum-bounces@ads.net [mailto:
br_forum-bounces@ads.net]
On Behalf Of Gabriel Bakker
Sent: Thursday, May 28, 2009 4:02 AM
To: Business Rules Forum
Subject: Re: [BR_forum] OOP and BR!
I use this technique all the time. Gordon is right, you don't have to search your code anywhere just to add additional parameters or additional local variables. If you add additional local variables, they just go at the end of your def fn statement, and you never have to worry. Now, if you use some sort of a symbol or system to indicate to you which variables are optional parameters and which are local variables, then you always know where to add local-scope variables in your parameter list and where to add optional parameters.
My function definitions look like this:
def fnSomething(var1$,var2$,var3;optional1,optional2$,___,local1$,local2$,local3$)
Of course the actual variable names I use are fairly long descriptive names. The "___" tells me that everything before this is a parameter, intended to be passed into the function, and everything after this is a local-scope variable.
I also use recursion, wherever it makes sense. The only problems I run into are the following:
1. Long variable parameter lists look messy. They are messy, but they are not particularly hard to deal with.
2. Arrays don't work. This is kind of a big problem.
ScreenIO screens call each other recursively. FnFM calls your screen. If you click on something that loads another screen, then it simply calls FnFM with the new screen, recursively. Because everything is declared on the parameter list, I have no problems with local variable scope. I did have problems with running out of workstack before I optomized the code. And those functions have a
lot of local-scope variables
and a lot of arrays. I had to introduce my own stack to store the values in the arrays, because BR won't do it for me. The result is code that is much more messy then it should have been, and that took much more time to write then it would have in another language. So thats why we really need to be able to declare local Arrays.
"
I’m not sure what you mean by “parameter lists need to have a separate parameter on each line along with the description of each parameter” could you elaborate a little please?"
What Gordon is talking about here is he's reccomending that you describe your parameters and your optional variables as comments in the beginning of your function:
def fnMagicGrid(filename$;row,col___,window,filehandle) ! Makes a magic grid out of a file using fileio
dim f$(1)*400, f(1)
dim form$(1)*255
! filename$ - the layout for the file to use
! row - optional starting row for the magic grid
! col - optional starting column for the magic grid
!
! window - the child window for the grid to live on
! filehandle - the file channel handle for the data file
!
! mat f$, mat f - the file record object
! mat form$ - the fileio form variable
let filehandle=fnopen(filename$,mat f$,mat f,mat form$,1)
do until file(filehandle)
...
...
loop
...
...
fnend
It is a good idea in practice anyway, but its tedious to do and most of the time I admit I don't end up doing it. Because of the way you have to declare your local variables on the parameter line, it just creates two complicated sets of lists to maintain.
Now, if Gordon could make it so that you can declare local scope variables in the usual way, then it would be much easier to document your code and to declare and maintain and read your local variables.
Gabriel
On Wed, May 27, 2009 at 6:30 PM, John Bowman <
gothnerd@gmail.com (
gothnerd@gmail.com)> wrote:
do you use this technique? do you use recursive functions? do you think it is a good viable solution that produces clean easy to read use and maintain code?
On Wed, May 27, 2009 at 6:24 PM, Gordon Dye <
gordon.dye@ads.net (
gordon.dye@ads.net)> wrote:
"
you now would have to search your system for all the calls to fn_whatever and see which optional parameters are being used and which are not… then (½hour later) you’re ready to insert a new variable into your def"
Not at all. As long as you inserted any new passed optional definitions ahead of the local variables and at the end of prior optional definitions, and you didn't change the meaning of any parameters, you would not care what other calls are passing.
local1 was just there for this example. I would expect you to preface your local variable portion of the parameter list with at least one obviously local name.
gordon
On Wed, May 27, 2009 at 4:15 PM, John Bowman <
gothnerd@gmail.com (
gothnerd@gmail.com)> wrote:
I understand what you are describing. My variable names are usually longer than local1, local3$. Ambiguous variable names (such as local1 and x) should never be used (IMHO). So in the real world you now would have to search your system for all the calls to fn_whatever and see which optional parameters are being used and which are not… then (½hour later) you’re ready to insert a new variable into your def.
I’m not using 4.2 yet, and I avoid recursive functions anyway, but I’d like my functions to be ready for recursion without having to rewrite them. As for the longer line length – that’s great, but a 1800 byte line is just sloppy code. Hard to read, can you quickly tell me what the 54th parameter is? No, neither can I.
I’m glad you’re looking at the array problem, it’s probably the most critical problem here.
I’m not sure what you mean by “parameter lists need to have a separate parameter on each line along with the description of each parameter” could you elaborate a little please?
-john
From: br_forum-bounces@ads.net (
br_forum-bounces@ads.net) [mailto:
br_forum-bounces@ads.net (
br_forum-bounces@ads.net)]
On Behalf Of Gordon Dye
Sent: Wednesday, May 27, 2009 4:05 PM
To: Business Rules Forum
Subject: Re: [BR_forum] OOP and BR!
There are a couple of misconceptions here.
First, John, what I am describing is:
DEF FN_WHATEVER(FIRST_REQ,SECOND_REQ$;FIRST_OPT,SECOND_OPT$,local1,local2,local3$*50)
If you need to pass an additional parameter you place it ahead of local1.
As for the source line length, that has been expanded to 2000 bytes in 4.2, so you can get a lot of long variable names in a parameter list. The compiled statement doesn't care about how long the name it. AA takes the same space as THE_FOURTH_ONE.
One point that I'm going to look into though, is redimensioning optional arrays passed and not passed. Local arrays are worthless as it stands. We didn't want to mess with anything sitting on the stack. But I think I know of a solution to this.
The other thing is, parameter lists need to have a separate parameter on each line along with the description of each parameter.
gordon
On Wed, May 27, 2009 at 3:11 PM, Gabriel Bakker <
gabriel.bakker@gmail.com (
gabriel.bakker@gmail.com)> wrote:
I declare every variable I use in a function as a local parameter by listing it in the def statement. I only ran into line length problems once but its a pretty significant problem.
Declaring every temp variable used in a function as a local parameter is a really good practice to get into. It keeps your functions from stepping on each others toes in random ways, and it encourages the use of cleaner code.
Of course, I have had to resort to major workarounds when I want to use an array in a function recursively. For that I have had to make my own stack and write functions for placing arrays on it and popping arrays off of it.
Also, I have found MyEdit's CTRL+SHIFT+UP/DOWN (search for next/prior occurrence of current word) can also be a useful tool when determining if a variable is unique or not.
Gabriel
On Wed, May 27, 2009 at 1:55 PM, John Bowman <
gothnerd@gmail.com (
gothnerd@gmail.com)> wrote:
And there are limits to the length of a line… this limits the name lengths/number of variables that you can have defined within the scope of a function. That’s another problem with this being the only way to make variables within the scope of a function. And as was pointed out earlier, in recursive functions EVERY variable used must be in the def statement. Let’s hope they use small variables like O and F and not Payee_Name_Last$ and Account_Balance$.
-john
From: br_forum-bounces@ads.net (
br_forum-bounces@ads.net) [mailto:
br_forum-bounces@ads.net (
br_forum-bounces@ads.net)]
On Behalf Of George Tisdale
Sent: Wednesday, May 27, 2009 1:45 PM
To: Business Rules Forum
Subject: Re: [BR_forum] OOP and BR!
I don’t think I see the problem. If the “local” variables are all optional after the semi-colon and therefore not referenced in the call adding a variable/parameter to be passed is as simple as adding it either before or after the semi-colon.
If added before the semicolon then all calls must reference the parameter or you will get an error on the call. If added immediately after the semi-colon then only those calls that need to pass the parameter need to be changed. All of the trailing optional parameters are left off the call and default to NULL.
George L. Tisdale, CPA
Tisdale CPA
75 Junction Square Drive
Concord, MA 01742
(978) 369-5585
From: br_forum-bounces@ads.net (
br_forum-bounces@ads.net) [mailto:
br_forum-bounces@ads.net (
br_forum-bounces@ads.net)]
On Behalf Of John Bowman
Sent: Wednesday, May 27, 2009 12:07 PM
To: Business Rules Forum
Subject: Re: [BR_forum] OOP and BR!
but the functions get too long so quickly and with no overloading going back and adding a variable that needs to be passed could be a real p.i.t.a. after you've put a huge list of scope-variables.
I don't understand what you mean by documenting the parameters? i just comments at the top of the function to do this.
On Wed, May 27, 2009 at 11:35 AM, Gordon Dye <
gordon.dye@ads.net (
gordon.dye@ads.net)> wrote:
I realize it would be useful to have a way to declare local variables. However, in the final analysis optional parameters can be used, with proper naming conventions, for local variables. And functionally nothing is lacking because all such variables are created fresh on the stack each time a function is called. What is needed, in my opinion, is some way to document parameters better than what is presently available.
gordon
On Wed, May 27, 2009 at 8:39 AM, John Bowman <
gothnerd@gmail.com (
gothnerd@gmail.com)> wrote:
Kenvin - today doing a recursive function - I got to apply your tip (below).
Thank you!
-john
-----Original Message-----
From:
br_forum-bounces@ads.net (
br_forum-bounces@ads.net) [mailto:
br_forum-bounces@ads.net (
br_forum-bounces@ads.net)] On Behalf Of
Kevin Klappstein
Sent: Wednesday, May 20, 2009 4:14 PM
To: Business Rules Forum
Subject: Re: [BR_forum] OOP and BR!
Another way to fake OOP (or more specifically variable scope) is to put
any variable that needs to remain in scope for the duration of a
function into the parameter list. This is the only place where BR has
proper variable scope, and will allow for the same function to be run
while the previous copy remains uncorrupted. This does cause problems in
that it makes your function calls look like a dog's breakfast, and you
can't cheat with using global variables between functions any more, but
it will work. We use this technique any time we need to use recursion.
Kevin Klappstein
Western Canadian Software
kevin@wcs.ab.ca (
kevin@wcs.ab.ca)
_______________________________________________
BR_forum mailing list
BR_forum@ads.net (
BR_forum@ads.net)
http://ads.net/mailman/listinfo/br_forum_ads.net
_______________________________________________
BR_forum mailing list
BR_forum@ads.net (
BR_forum@ads.net)
http://ads.net/mailman/listinfo/br_forum_ads.net
_______________________________________________
BR_forum mailing list
BR_forum@ads.net (
BR_forum@ads.net)
http://ads.net/mailman/listinfo/br_forum_ads.net
_______________________________________________
BR_forum mailing list
BR_forum@ads.net (
BR_forum@ads.net)
http://ads.net/mailman/listinfo/br_forum_ads.net
_______________________________________________
BR_forum mailing list
BR_forum@ads.net (
BR_forum@ads.net)
http://ads.net/mailman/listinfo/br_forum_ads.net
_______________________________________________
BR_forum mailing list
BR_forum@ads.net (
BR_forum@ads.net)
http://ads.net/mailman/listinfo/br_forum_ads.net