HP-50g Local variable and Global variable confusion - Printable Version +- HP Forums (https://www.hpmuseum.org/forum) +-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html) +--- Forum: General Forum (/forum-4.html) +--- Thread: HP-50g Local variable and Global variable confusion (/thread-8129.html) HP-50g Local variable and Global variable confusion - rui.c.sousa.99 - 04-07-2017 09:44 AM I have a question that happen in HP-50, and I think also on the HP-48 Local variables (LAMs) and global variables (ID) appear identically on the stack, and yet they are differente entities if you define an expression and use a variable that exist as a local variable, that expresison will have a LAM in it. if the local variable don't exist, it will have an ID in it. For example running the following program << '2*X' -- Simple expression DUP ->S2 -- Decompile it 5 -> X << -- local variable with a dummy value '2*X' -- Same expression, but a local variable exists DUP ->S2 -- Decompile it >> >> will produce this on the stack '2*X' "SYMBOL %2 ID X x* ; " '2*X' "SYMBOL %2 LAM X x* ; " They appear iddentically, but internally are different This poses-me a question. How do we store algebraics and then use then in a local variable environment. For example, the following won't work: << '2*X' 'F' STO -- Store expression in variable F 5 -> X << -- Define local variable X -- try different alternative ways to Recall F and evaluate it using X =5, -- none work, because ID X is different from LAM X F EVAL 'F' RCL EVAL F ->NUM -- This one work, but involves conversion to string, with also have side effects F ->STR STR-> EVAL >> >> This also prone to cause bugs. If in the above program there was a global variable X, for example, executing previously 10 'X' STO and then run the above program, all the functions would return 20 (and the last one return 10, becauses the string conversion re-parses the algebraic and uses the local variable) How to force algebraics to use local variables? I also tried the | operator: '2*X|X=X' without success I know I can use the | operator, but I have to know what variables exist in the expression, and it is so complicated and slow: For example '2*X' 'F' STO --- algebraic with global symbol {X} 'V' STO --- variable, in a list, X is also a global symbol then in the local environment (X exist as a local variable): F --- RCL F : '2*X' V ---- RCL V : {X} X ---- RCL X (local variable value) : for example 5 + --- Add to the list : {X 5 } | --- Replace X : '2*5' And repeat to to every variable Also, another question, the VARS command shows the global vars, how can we know the local vars that exist Thanks RE: HP-50g Local variable and Global variable confusion - Han - 04-07-2017 05:28 PM Create F as a function instead of an expression. 'F(X) = 2*X' DEFINE creates a variable F whose content is \<< \-> X '2*X' \>> Then just use something like \<< 5 F \>> to evaluate F at X=5. Quote:Also, another question, the VARS command shows the global vars, how can we know the local vars that exist Local variables only exist during runtime. RE: HP-50g Local variable and Global variable confusion - TravisE - 04-08-2017 09:28 PM ^ Local variables can exist during interactive operation when a program executes HALT within a local variable block. However, I don't know of a built-in way to display a list of current local variables. At any rate, they will be automatically destroyed once all suspended programs are allowed to continue to completion or the KILL command is executed. One way to refer to local variables in an expression (this works on the 50g; I don't recall on which model this feature was first introduced) is to name the variable starting with a left-arrow (←) character. The editor will always compile variables with such names to refer to local variables, whether or not they actually exist at compile time. The following, for instance, should return 10 when executed: Code: ```« '2*←X' 'F' STO   5 → ←X « F EVAL » »``` RE: HP-50g Local variable and Global variable confusion - rui.c.sousa.99 - 04-10-2017 10:30 AM Thank you for your replies. Yes, I knew about compiled local variables, but I didn't realize that they where automatic compiled do LAMs. But their name are awkward Also I didn't remember DEFINE, but this mean defining a new function, when I'm inside one (I'll try to explain what I'm trying to do) I was investigating the HP50g programming model which is interesting because it is unusual. But as the same time it is so confusing What I was try to do, was to explore the IFTE bug in the Plot functions, in hp50g version 2.15. I'm writing the following code by memory, so there may be errors the following function Y1(X) = IFTE(X>=0, X^2, COS(X)) don´t plot because of the IFTE bug So I changed the IFTE into a custom function, MYIF: Y1(X) = MYIF(X>=0, X^2, COS(X)) << -> T V1 V2 << T V1 V2 IFTE >> >> 'MYIF' STO The above don't plot either. But I could see what was going on, by logging: {} 'log' STO << -> T V1 V2 << log T + V1 + V2 + 'log' STO T V1 V2 IFTE >> >> 'MYIF' STO I realize that the plot system invoke the function with X as an argument, and if the result is an algebraic it will use that algebraic and never call the function again. I guess this speed up the plotting. The above function was called only once because it return an algebraic, 'IFTE(...,...,...)' and the bug still exists So I changed to: (removed the log part) << -> T V1 V2 << IF T THEN V1 ELSE V2 END >> >> 'MYIF' STO This new MYIF function errors when T cannot be evaluated, so the plot system realized that the function has to be called for every X. But this function plots correctly but it is quite slow So I wanted the above MYIF function not to error when X was used as an argument, but to return a special version of it, in algebraic form, that the plot system could then plot directly and correctly So I changed it to, or to something similar to this: << -> T V1 V2 << IFERR IF T THEN V1 ELSE V2 END ELSE 'IFTE(T,V1,V2)' END>> >> 'MYIF' STO I realize the above didn't work out, I dont remember what happend, but I think T, V1, V2 weren't replaced inside the algebraic, so I tried to use EVAL, and the algebraic errored... The only way I managed it to work was to use a string, something like this: << -> T V1 V2 << IFERR IF T THEN V1 ELSE V2 END ELSE "'IFTE(" T + "," + V1 + "," V2 + ")" + STR-> END>> >> 'MYIF' STO This returned the algebraic correctly, but in some situations was returned like this: 'IFTE(...,...,...) | (X=X)'. I don't remember when this happen When this was latter plotted it plotted random numbers. This is confusing, and was related to the | operator. Investigating a little more (I created another function MY2IF - similar to MYIF - , to work simultaneous with the MYIF: First MYIF was called by the plot System, with X as argument. MYIF return the following algebraic 'MY2IF(...,...,..)'. This, I don't know why is transformed into 'MY2IF(...,...,...)|(X=X)". Then the plot system invoke this new function MY2IF. But a random number appear in place of X. MY2IF received the following argument as T: '0.51453455'>=0 V1: '0.51453455' ^2 V2: COS('0.51453455') I realize this is the way the | operator work. It uses a random number as the substituting value. But it is not a number, it is a symbol whose name is a number, decompiling T : ID 0.51453455 %0 x>= so the number is treated as a symbol and it don't return true of false when evalutated At the end of the function the OS replaces the value 0.51453455 with the correct value Opening a parethesis: the way the | operator work: imagine the following simple function << -> X <>>> 'F' STO now call 'F(X)|(X=W)' EVAL put some HALT happen inside F, X is not W, but it is for example '.4533232' (a symbol, not a number). then it is squared: '.4533232 ^2' This algebraic is returned at the end, but on the stack appears W^2... this suggest that the OS change the "number" correctly to "W" End of parenthesis Returning to MY2F: then T is evaluated, it will error and the error trap returned a string 'MY2IF( 0.51453455>=0, '0.51453455^2, COS(0.51453455))' so the random symbol name is plotted like a number... So I want if to be able to create an algebraic but keeping '0.51453455' as a symbol, not a number...lolol What a mess...lolol