[question]userRPL, functions or (sub)subprograms and directories
|
03-29-2017, 10:36 AM
(This post was last modified: 05-21-2018 12:51 PM by pier4r.)
Post: #1
|
|||
|
|||
[question]userRPL, functions or (sub)subprograms and directories
A basic program in userRPL that makes use of local variables and no algebraic expression is the following (If Im not mistaken)
Code:
Now when programs gets a bit more complicated (note1) I usually try to use functions to split it in blocks. As far as I know there are at least two ways to emulate a function: - either I produce functions in different source files, that then I save as programs. So I have: function1 <prog> function2 <prog> main <prog> Where main makes use of function1 and function2 - or I somehow type the function in the main program and the store it to use it as recalling a variable. Like Code:
Are there better ways? So far I prefer the second way (unless the program is awfully long, like 2Kb or more comments excluded) because I can use functions as defined in the main program, and not floating around the memory and maintained separatedly. Nevertheless I do not know if there may be cases that a variable cannot hold a program. I tried to search on this site but I get interesting but not useful discussions like this. (note 1) yes I know, ideally I should move to sysRPL or hpGCC or maybe the lua interpreter built with hpgCC, but I did not finish exploring the RPL commands in the AUR) Wikis are great, Contribute :) |
|||
03-29-2017, 11:36 AM
Post: #2
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
You do not need to store your functions; you can have the functions be arguments themselves:
Code: \<< Graph 3D | QPI | SolveSys |
|||
03-29-2017, 11:51 AM
Post: #3
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
True. That would help ordering the code better. Any other tip?
Wikis are great, Contribute :) |
|||
03-29-2017, 12:43 PM
(This post was last modified: 03-29-2017 12:43 PM by Vtile.)
Post: #4
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
You can use if error (IFERR) as a some form of escape structure.
|
|||
03-29-2017, 12:51 PM
Post: #5
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
(03-29-2017 12:43 PM)Vtile Wrote: You can use if error (IFERR) as a some form of escape structure. Yes. I knew this and recently I stumbled over a discussion that quickly moved from "how to simulate a break" to "how to avoid it and why". Anyway my request for additional tips was mostly about "any other best practice how to code and use functions that are needed mainly by one main program?". Wikis are great, Contribute :) |
|||
03-29-2017, 02:44 PM
Post: #6
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
(03-29-2017 12:51 PM)pier4r Wrote: Anyway my request for additional tips was mostly about "any other best practice how to code and use functions that are needed mainly by one main program?". I believe you've already found what is likely the best way to create and use embedded functions and subroutines for UserRPL -- create them as local vars and activate with local EVAL. This method keeps the source code together as a single object and is efficient with memory resources. The only downside that comes to mind for something like this might be performance, though only in situations where the function/subroutine is called many times. You're not likely to notice any performance issues for functions that are only used a few times. As you've already pointed out, storing programs/data into other user objects [aka globals] is a possibility. One additional advantage that this method brings is that you can use the object's location in your directory structure to control its scope. While this probably doesn't apply to what you originally intended, it's a worthy consideration for other situations, especially when different versions of the same function might apply to different scenarios. I'd be remiss if I didn't mention a third possibility, though it's fair to say that it's probably the least applicable in this case. That would be creating a custom library to contain your programs and data in a single coherent package. The overhead required makes this less feasible for simple situations, but it brings some nice benefits to projects with greater complexity or when you want to start controlling the "exposure" of individual elements of the application. |
|||
03-29-2017, 03:01 PM
(This post was last modified: 03-29-2017 03:01 PM by pier4r.)
Post: #7
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
(03-29-2017 02:44 PM)DavidM Wrote: -cut - Nice input, thanks! I did not thought about the solution with main program and subprograms in a subdirectory. Somehow I can do it with PHP, JAVA and so on and I think instead that userRPL is flat. I could use a local var to define the source path and that's it, well actually I never used absolute paths with directories on the 50g. For libraries, yes it is a possibility but to me that is for fairly big programs or at least stable ones (and at that point I would try to go on hpgcc if I have to handle overhead). Wikis are great, Contribute :) |
|||
03-29-2017, 03:37 PM
Post: #8
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
(03-29-2017 03:01 PM)pier4r Wrote: I could use a local var to define the source path and that's it, well actually I never used absolute paths with directories on the 50g. That's one way to approach it, but not exactly what I meant. Keep in mind that the default search path for objects on the 50g is "current directory or any parent directory of the current one". So you don't have to specify the full path if the item being referenced is located anywhere in that upward-looking default search path. Objects in any directory are accessible to other objects in that same directory or any of its subdirectories without specifying the full path name. Multiple versions of the same object can be saved in different subdirectories, and the first one found on the search path will be used. This is why an item named 'FOO' stored in the HOME directory can be accessed by any other object (in any subdirectory) simply as 'FOO' (without a path). Objects in the HOME directory are always in the search path. Note that this behavior can be a mixed blessing, and is quite often the cause of confusion when people have stored objects somewhere in a parent directory and their programs (or built-in functions) access them. Used properly, though, it can be quite powerful. |
|||
03-29-2017, 04:42 PM
Post: #9
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
(03-29-2017 03:37 PM)DavidM Wrote: That's one way to approach it, but not exactly what I meant. Keep in mind that the default search path for objects on the 50g is "current directory or any parent directory of the current one". So you don't have to specify the full path if the item being referenced is located anywhere in that upward-looking default search path. Yes, I agree that's quite powerful. I did not know this property of the interpreter. Is it defined in the manuals or is it something that the community discovered and was underdocumented? Anyway I noticed a pretty useful usage of putting an additional nested program in a program. One can isolate code blocks to not execute them (in the case adding a "drop" after the nested program) or to debug them. That helps a lot. Code:
Wikis are great, Contribute :) |
|||
03-29-2017, 05:39 PM
Post: #10
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
(03-29-2017 04:42 PM)pier4r Wrote: Is it defined in the manuals or is it something that the community discovered and was underdocumented? It's defined in the 50g Users Guide (English version) on page 21-4, and I believe in other documents as well. Sometimes sample code can show how things work more clearly than lengthy descriptions: Code: %%HP: T(3)A(R)F(.); Running "test" in each directory will give different results due to the variables "foo" and "bar" being redefined. Note that neither the function calls nor the variable references need paths -- the O/S simply looks for the named objects and executes the first one it finds with that name in the current search path. This example shows another important concept to keep in mind: while "test" in dir2 and dir3 is actually running a program (foobar) that resides in a higher level directory, the search path that applies is whichever one was current when you started "test" -- not the path starting from the location of "foobar". The current path always starts at the current directory that the user sets, unless (of course) the program explicitly changes that. |
|||
03-29-2017, 05:48 PM
(This post was last modified: 03-29-2017 06:08 PM by pier4r.)
Post: #11
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
(03-29-2017 05:39 PM)DavidM Wrote: This example shows another important concept to keep in mind: while "test" in dir2 and dir3 is actually running a program (foobar) that resides in a higher level directory, the search path that applies is whichever one was current when you started "test" -- not the path starting from the location of "foobar". The current path always starts at the current directory that the user sets, unless (of course) the program explicitly changes that. Like in linux. Nice. Another thing that is pretty neat is that I did not know I could code directly directories in an object. I do not know if that is a made up object or you can implement an entire directory in a so simple way. I'll test asap. It is exciting! Compared to that my way of coding programs with functions is way more complicated (either because I have one lengthy program with inner blocks or because I need a multi tabbed editor to keep track of things). Anyway I never read about the DIR in the user guide or AUR (wait AUR mention it, but quickly), but again, as I missed the point about visibility of saved globals in subdirectors in the user guide, I may have missed the part about "how to code an entire directory structure". Coding directly a directory structure I believe could be even more "maintainable" than a program between "\<< \>>" that has multiple sub blocks inside it. Wikis are great, Contribute :) |
|||
03-29-2017, 06:15 PM
(This post was last modified: 04-17-2017 03:59 PM by pier4r.)
Post: #12
|
|||
|
|||
about DIR END
About DIR ... END
Awesome, it works! I used your example (thanks a lot!) to infer the structure but I'm not sure how the structure should be within DIR ... END . If someone could point out more documentation it would be great. For the moment I found a passing note in the AUR and only one other post on this site using DIR ... END http://www.hpmuseum.org/cgi-sys/cgiwrap/...ead=138380 message number 8. I'll search more but now I will think about converting the program that I was writing. Side note: Gerson if you will ever read this thread. You are a very prolific writer about user RPL programs and mathematical solutions, but as a reader of your code I see that you heavily use the stack (that is not easy to read nor debug) and you put almost no comments in your programs. So one is left debugging them to understand what happens. Could you put more comments in them? Would be great! :love: Update: I found some more usage of DIR END (especially compsystem) but no direct documentation about the format of the entries. Updated2: so, a bit of satisfying entries Equation library with DIR END by J.H. Meyers DIR end structure comp.sys.hp48 DIR END structure, for SYSRPL I believe - http://www.hpmuseum.org/forum/thread-4184.html Wikis are great, Contribute :) |
|||
03-29-2017, 06:30 PM
(This post was last modified: 03-29-2017 06:30 PM by pier4r.)
Post: #13
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
So I would like to post the following code to help possible newbies like me (I'm no newcomer, I'm just noob).
I edited with notepad++ using "language ->N - Normal text" and then the chapter J of the AUR to help me with the translation of special chars that are not available in plain text. The following code contains subprograms that can be easily disabled, for debugging purposes, avoiding to execute EVAL after them or after recalling them. In the same way, if instead of EVAL, DBUG is used, then the user can DBUG exactly the wanted block and nothing else, simply evaluating the main program (The execution will stop once DBUG is reached, then one can proceed with the RUN & DEBUG menu). Speeding up the identification of problems. Once I discover this the debugging of quirks in the program was way faster than my previous experiences. It is something should be more advertised for newcomers, I wish I would known before. Then I suppose the directory structure in one source file would be even better but it is something I'm going to use after this post for the first time. Code:
Wikis are great, Contribute :) |
|||
03-29-2017, 07:42 PM
(This post was last modified: 03-29-2017 08:53 PM by pier4r.)
Post: #14
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
If I use a DIR ... END structure (see previous posts) is there a way to pass variables that are not globals, that AFAIK are pretty slow in userRPL, between subprograms in a smart way or I have to pass every time the variables leaving a copy on the stack as usual?
Update1: so far instead of passing long lists of local variables I just decided to use globals. Maintenance value > speed value (because with 'easier' code one gets correct results, with premature optimizations one gets necklaces of fails) Wikis are great, Contribute :) |
|||
03-29-2017, 08:53 PM
Post: #15
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
Use \<-varname to create local variables that are visible between subprograms. I believe this is discussed in the Advanced User's Reference manual (for the HP48 at least).
Graph 3D | QPI | SolveSys |
|||
03-29-2017, 09:48 PM
Post: #16
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
Do you mean the compiled local variables? I never used them but I'll have a look. Thanks.
Wikis are great, Contribute :) |
|||
03-29-2017, 11:07 PM
Post: #17
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
Regarding directory syntax:
In the context of RPL, directories are simply another type of object. They're actually conceptually similar to other compound objects such as lists, in that they encapsulate other objects into a single entity. So, like the syntax for lists ( { obj1 obj2 ... objN } ), the syntax for notating a directory object simply consists of a prefix (DIR), the contents (<whatever>*), then a suffix (END). The syntax of notating a directory object's contents (<whatever>*) is an arbitrary sequence of 0 or more object id/definition pairs. So you could designate the syntax as follows: Code: DIR <obj1_ID> <obj1> <obj2_ID> <obj2> ... <objN_ID> <objN> END Unlike lists, there's very little you can actually do with directory objects other than recalling them to the stack or storing them into variables. Their usefulness comes from the kernel knowing how to deal with them directly, which it exposes through the user interface, dedicated variables (such as HOME), and directory-specific commands and features (PATH, ORDER, CRDIR, PGDIR, etc.). All of the IDs in a directory definition have to be valid RPL IDs, and all of the objects have to be valid single RPL objects. The objects themselves can be any valid RPL type that could normally be stored into a variable, including other directories. So, for example, all of the following are valid directory designations: A directory containing three numeric objects: Code: DIR a 1 b 2 c 3 END A directory containing two lists and an algebraic: Code: DIR a { 1 2 3 } b { 4 5 6 } c '(x+y)/z' END A directory containing a single program named 'myprog': Code: DIR myprog \<< 1 + 5 / SQ \>> END A directory containing a single directory with no objects: Code: DIR emptydir DIR END END I've put all of the above on a single line to show the minimal syntax, but you can add newlines/indentation as desired for readability: Code: DIR |
|||
03-30-2017, 06:23 AM
Post: #18
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
Nice! A thousand thanks!
Wikis are great, Contribute :) |
|||
04-03-2017, 07:24 PM
Post: #19
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
One other point that I didn't see here: writing to global variables is very expensive. Because the entire contents of the HOME directory is packed tightly together, changing the size of any object means you have to move every object that comes after it. And since you have to move objects, you also have to check the stack, return stack, local variables etc for any pointers to the objects that moved and adjust them accordingly. Thus writing to local variables is much faster.
|
|||
04-03-2017, 08:05 PM
Post: #20
|
|||
|
|||
RE: [question]userRPL and functions or (sub)subprograms
Oh, did not know that. Thanks for sharing! So now I understand why the more "garbage" I left in the Home, the more time some actions take.
Wikis are great, Contribute :) |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 2 Guest(s)