Problems with SafeFileTrash and ArraySubset

After lurking in great anticipation of PanX I finally have time to start converting my couple decades of old Pan files. Most things I’ve tested worked or had well documented tweaks available. I do have one possible bug, a question and a couple suggestions for the wish list to offer:

  1. SafeFileTrash is listed in Panorama X’s help and is not listed as Unimplemented, but on converting multiple Pan6 files, where it had worked fine, it shows as an error in the Procedure Editor:

Unknown statement: safefiletrash as if it weren’t implemented, even when coped from Help and pasted there. I’m running 0.9.002 on 10.11.6. I use it to delete temporary files I circumstantially may or may not have created upstream to avoid additional error handling.

  1. The one listed as not yet implemented statement I’d used in several places that lacked an clear replacement was ArraySubset. Would the following be an appropriate replacement or can someone suggest something better or faster?

    outputArray="“
    looparray inputArray, sep, element
    outputArray= outputArray+?(formula,sep+element,”")
    endloop
    outputArray=arraystrip(outputArray,sep) ;to remove the leading blank created

  2. Being able to copy/paste from Help is an improvement, especially for less familiar functions and statements. But, for familiar ones too long to just type Pan6’s contextual menu entry of many functions and statements or Pan6’s Programming Assistant were faster. Jim has posted here that adding contextual menu input of functions and statements would non-trivial and impractical due to both their increased numbers and Apple’s code. I can live with just contextual entry of field, form and procedure names, which will save many typos. If contextual entry of open database names could be easily added, that would also be nice. A HotKey to Clairvoyant entry, like the Pan6 Programming Assistant, would be awesome. Hopefully that could be recreated mostly using PanX code to simplify its creation and maintenance by Jim.

I can confirm this.

This is simpler than your solution:

local outputArray, inputArray, Sep
inputArray="red,green,orange,blue,yellow,purple,white,black,silver,gold,bronze,copper"
Sep = ","
outputArray = arraystrip(arrayfilter(inputArray,Sep,{?(import() contains "a",import(),"")}),Sep)

which is basically what the Panorama 6 ArraySubset statement did.

I leave this one to Jim

Filetrash seems to work, evoking the new Fileerase. It is simple enough to trap an error, so you could add SafeFileTrash as a custom statement.

I complained about the inappropriate contextual menus not long ago. Apparently that is difficult to implement.

  1. I don’t know how safefiletrash got into the documentation without being implemented. It’s so trivial that I just went ahead and implemented it right now rather than filing a bug report! So it will be in the next version.

  2. It is my belief that ArraySubset does not work properly in Panorama 6. If someone got it to work that would be news to me. So I didn’t put very high priority on implementing it in Panorama X.

Thanks! Your alternative to arraystrip worked, at least when the {} extra level of quotes was included. And seemed to have similar speed. Without the {} in pan6 it fails with “Runtime error in call( procedure.” I presume the extra quotes changed the evaluation order to let it work, and have seen some discussion on double quoting in the forum. But I don’t yet understand when and where to use them. I was surprised Jim said he hadn’t though ArraySubset worked in 6. My experience was ArraySubset with import() in the formula worked in 6, but ArrayFilter with import() in the formula hadn’t worked. But I’d never double quoted such formulas.

In a function, every parameter is a formula. The value of that formula is determined before the function is called, and it’s that value that gets passed to the function. The function only sees the value. It does not see the formula that was used to produce it.

arrayfilter(inputArray,Sep,{?(import() contains "a",import(),"")})

With the {} the value of the third parameter above is simply the text between the {} quotes.

?(import() contains “a”,import(),“”)

In other words, it’s the text of a formula. It’s that text which will be passed to the arrayfilter( function as the third parameter. Arrayfilter( needs that formula, because it needs to evaluate it repeatedly, once for each element of the array.

Without the {} quotes, Panorama will try to evaluate ?(import() contains "a",import(),"") before it calls arrayfilter(, and pass the result of that one evaluation as the value of the parameter. The result of that one evaluation will be an error, because the import() function makes no sense in that context.

Even if there were no error, receiving the value of a single evaluation is no help to arrayfilter(. It needs to know the formula itself.

Commands, unlike functions, can’t be nested. For them, it is not necessary for the values of their parameters to be determined before the command is called. The command can see the raw text of the parameter, and evaluate those that need to be evaluated.

arrayfilter inputArray,outputArray,Sep,?(import() contains "a",import(),"")

In this case the arrayfilter command wants to evaluate the first and third parameters once each. It wants to evaluate the fourth parameter multiple times, and it doesn’t want to evaluate the second parameter at all. The second and fourth parameters aren’t quoted because it isn’t necessary to do that to prevent them from being evaluated in advance. That wasn’t going to happen anyway.

Excellent explanation. Now the concept makes since. Now to find some more places to use it in my own code to better lock it in my own memory.