How to create custom function from custom statement in Pan 6?


#1

This is relocated and reworded from a post in the QNA forum.

I have several custom statements which I want to offer as functions, presumably using the call( function.

I keep getting error messages when I enter stuff into the Custom Functions (User) database. I thought they might relate to my custom statement so I tried making a custom function of an existing statement (arrayintegersort), setting it up in the Custom Functions (User):List form, as follows:

Under Name, I entered srt(thearray,thesep)
In Body, I entered call("_ArrayLib",“arrayintegersort”,thearray,thesep)
In test data I entered "6,8,2,5,8",","

Tabbing through to the end, there are no errors but no result is calculated.

If I capitalise the statement name to
call("_ArrayLib",“ARRAYINTEGERSORT”,thearray,thesep)

I get a “run time error in call( procedure” message

I tried using the full path to _ArrayLib, as in

call(folderpath(info("panoramafolder")) + 
"Extensions:Libraries:_ArrayLib","arrayintegersort",thearray,thesep)

but the message stayed the same. If I capitalise the statement name with a full path name,

call(folderpath(info("panoramafolder")) + 
"Extensions:Libraries:_ArrayLib","ARRAYINTEGERSORT",thearray,thesep)

there are no error messages but again, no result is calculated.

What’s wrong with this code and what’s the solution to creating a function for a custom statement in a database called “Maths” in the Panorama Libraries folder?

michael


#2

There is no correct way to invoke the ARRAYINTEGERSORT statement as a function. You can’t just take any arbitrary code and use it as a function, the code has to be written to be a function, and ARRAYINTEGERSORT wasn’t written that way.

In the case of ARRAYINTEGERSORT, it has three parameters. The second parameter is used to return the sorted array, it uses the setparameter statement to do that. The setparameter statement is not allowed in a procedure called in a function. Instead, the procedure is supposed to use the functionvalue statement to return the value.

The closest you got to working was:

call("_ArrayLib","ARRAYINTEGERSORT",thearray,thesep)

When you did that you got a runtime error, and that was correct!! This error would have been the line that contains the parameter(3) function, since there is no parameter 3, that generates an error. Had the procedure gotten further, it would also have gotten an error when it got to the setparameter statement.

One problem I see is that apparently in Panorama 6 it would not generate an error message if the database or procedure name was incorrect.This has been changed in Panorama X, so all of your examples would have produced errors in Panorama X. (I didn’t test this in Panorama 6 myself, I am going on your reports, but I did test it in Panorama X.)


#3

I don’t want to take up your time Jim - you have enough on your plate with PanX. But, in Panorama Reference, I looked at the ARRAYFILTER statement which has four parameters,
oldarray, newarray, separator, formula
and then at the arrayfilter( function which has three of those parameters and appears to be invoked by
call("_ArrayLib","ArrayFilter",thearray,thesep,theformula)
I was trying to emulate that process.

I understand your point about the problems of setparameter and parameter(3) - I’ll play around with writing the function code.

m


#4

The ARRAYFILTER statement is not a custom statement. That statement has been around since Panorama 3. Custom statements were introduced by Panorama 5. The ArrayFilter procedure that the call( function is calling is in a custom statement library, because they open in secret when Panorama launches, and stay open until it quits. Putting lower case letters in its name prevents it from being registered as a custom statement.

The code in that procedure is

local newarray executelocal {arrayfilter parameter(1),newarray,parameter(2),}+parameter(3) functionvalue newarray

If you open the Custom Statements wizard and click on “_ArrayLib” you will see a list of the custom statements in that library. Hold the control key down and click again, and that list will get longer. Now it shows all the procedures in that library, not just the custom statements. Double-click on any of the procedures to open it for inspection.

The strategy used for arrayfilter( should work for any of your custom statements which return a single value as the result. Write a procedure with lower case letters in its name, and put it in the library. Have that procedure use the statement to get a result, and then return the result with a functionvalue command.


#5

I understand that the ARRAYFILTER statement is not a custom statement. I was using it as a test bed in case there was a problem in using one of my custom statements. My theory was it might be easier to make it work with an existing statement than with one of mine.

But thanks for that info on the secret files (don’t tell the Russians:) - I’d sort of worked out that something like that was happening because of the differing responses to upper and lower case arguments.

In fact, between the last para and this one, I created a simple lower-case custom statement and successfully called it from another database. I may now have some idea of what I’m doing.

m