fbpx
Welcome, Guest
Username: Password: Remember me
This public forum is meant for questions and discussions about Visual FoxPro
  • Page:
  • 1

TOPIC:

Input needed on FoxPro array support 23 Nov 2020 22:07 #16750

  • robert's Avatar

  • robert

  • Topic Author


  • Posts: 2023
  • We are working on the implementation of the FoxPro array support.
    From what we have seen the FoxPro arrays are one dimensional arrays that also support a 2 dimensional indexes.
    You can declare an array like this
    Dimension myArray(2,2)
    myArray(1,1) = 1
    myArray(1,2) = 2
    myArray(2,1) = 3
    myArray(2,2) = 4
    and then access
    myArray(4) and see the value 4.

    or
    Redimension the array to
    Dimension myArray(4)
    and see that the contents has been saved and the elements have the values 1 through 4.

    We have this working.

    However this works quite different from the array support that we already have in the system, which is based on the Clipper array support (sometimes also called Ragged Arrays) where each array is in fact a single dimensional array, but the elements of the array can also be arrays, which allows unlimited nested arrays. This array support is also available in Visual Objects, Vulcan and Xbase++.

    The questions that we have are:
    1) In the FoxPro dialect should there be both the FoxPro compatible arrays (for example declared with the Dimension keyword) and Clipper compatible (Ragged) arrays ? Or should we map the ARRAY keyword in the FoxPro dialect to the special FoxPro array type?
    2) There are many functions in the FoxPro runtime that take an not declared, unitialized array and fill the array. See for example this code from the VFP helpfile:
    Set PATH TO (HOME(2) + 'data\')     && Sets path to database
    Open Database testdata && Opens the database
    ? ADatabases(gaDatabase)     && Creates an array of open databases

    As you can see gaDatabase is not declared and not initialized. The runtime magically creates the array inside the ADatabases() function and adds it as private to the function that called it.

    In most other XBase dialects you would write it like this
    LOCAL gaDatabase           && declare the array (could also be PRIVATE gaDatabase)
    ? ADatabases(@gaDatabase)     && pass the array by reference so ADatabases() can create it 

    or
    LOCAL gaDatabase           && declare the array (could also be PRIVATE gaDatabase)
    gaDatabase = ADatabases()      && then the array gets returned, but we loose the numeric return value

    How common is this kind of code (like the example from the help file) in your code? Would it be a problem to require people to declare the private first. We can add the @ character automatically in the compiler. We already have support for that.

    If it is a problem to require people to declare the variable first then it would also be possible to mark functions such as ADatabase() with a special attribute in the runtime, so the compiler "knows" that this is a function that may create a new local and then it can automatically generate a private (or local) declaration at compile time.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Input needed on FoxPro array support 25 Nov 2020 23:15 #16762

  • atlopes's Avatar

  • atlopes


  • Posts: 64
  • Robert,

    I'll try to refer to as many points as possible and number them in the process to facilitate further references.
    1. DIMENSION an array not previously declared creates a PRIVATE array.
    2. DIMENSION an array that was previously declared respects the current scope of the array (PUBLIC, PRIVATE, or LOCAL).
    3. All elements of a DIMENSIONed or LOCAL ARRAY are initialized to FALSE.
    4. All the Axxxx() functions that populate an array with some content start by creating a PRIVATE array if it does not exists. Otherwise, they operate as the DIMENSION command.
    5. The first parameter of the Axxxx() functions is passed by reference.
    6. Elements of a bidimensional array can be addressed as if the array is unidimensional (the contrary is not supported).
    7. The array can be used as a simple variable (if Qry is the name of an array, ? Qry is possible and refers to the first element of the array).
    8. All elements of the array can be assigned at once with a single statement (Qry = "x" stores the value "x" to all elements, no matter if the array is bi or unidimensional).
    9. Arrays can be a property of a class, declared as DIMENSION propertyName(initialDimension) in the property section of the class definition.
    10. An array property can also be added to an object in run time using the ADDPROPERTY() function or the AddProperty() method of containers.
    11. Imposing the need for variable declaration - arrays or not - will break lots of VFP code. Is it possible for a pre-processor to look for undeclared variables and make the necessary amends (at least for arrays)?

    Other aspects may come to mind with further discussion. I hope this covers most of the behavior that will require your attention.

    Please Log in or Create an account to join the conversation.

    Input needed on FoxPro array support 26 Nov 2020 09:12 #16763

  • robert's Avatar

  • robert

  • Topic Author


  • Posts: 2023
  • Antonio,
    Thanks for your input.
    What about question 1:
    In the FoxPro dialect should there be both the FoxPro compatible arrays (for example declared with the Dimension keyword) and Clipper compatible (Ragged) arrays ? Or should we map the ARRAY keyword in the FoxPro dialect to the special FoxPro array type?

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Input needed on FoxPro array support 26 Nov 2020 21:52 #16771

  • atlopes's Avatar

  • atlopes


  • Posts: 64
  • Robert,

    As a rule of thumb, I would prefer a combination of retro compatibility support with additional features. Of course, I cannot fathom the dimension (sorry for the pun...) of the task.

    Please Log in or Create an account to join the conversation.

    Input needed on FoxPro array support 26 Nov 2020 23:05 #16772

  • robert's Avatar

  • robert

  • Topic Author


  • Posts: 2023
  • Antonio,
    So would it be OK with you if the Dimension and Declare statements produce a FoxPro compatible array (as well as functions like ADatabases).
    And a declaration like
    LOCAL myArray AS ARRAY
    or
    VAR myArray := {1,2,3}
    would then produce a Clipper compatible array, that can grow with functions such as AAdd()

    Robert

    PS Is there a syntax for a "literal array" in FoxPro? I have not found it.
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Input needed on FoxPro array support 27 Nov 2020 17:37 #16781

  • atlopes's Avatar

  • atlopes


  • Posts: 64
  • Robert,

    Yes, I think that the way you're proposing would be great. Just a note I would like to add: the syntax
    PUBLIC ARRAY x(1)
    LOCAL ARRAY y(1)
    should also produce FoxPro like arrays (scoped as the declaration suggests).

    I can confirm that there is no way to create literal arrays in FoxPro.

    Please Log in or Create an account to join the conversation.

    Input needed on FoxPro array support 27 Nov 2020 17:38 #16783

  • robert's Avatar

  • robert

  • Topic Author


  • Posts: 2023
  • Antonio,
    Thanks.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Input needed on FoxPro array support 29 Nov 2020 20:01 #16791

  • mainhatten's Avatar

  • mainhatten


  • Posts: 161
  • Hi Robert,
    Antonio already ticked off most of the things to watch out for. Only a few things left unsaid after on 27. adding local [ARRAY] la(arraydim):
    Numbering to his first answer:
    4 ) vfp will check whether the first parameter exists or not - but if it exists it is also checked if it really is a vfp Array, otherwise error.
    8 ) the ability to set all array elements with a single line without referring array element like
    laMyArray = luForWholeArray
    this encompasses only simple data types like strings, dates or numbers - you cannot assign an object to all array elements at once, those must be assigned to individual array elements.
    9 and 10: for me one of the more illogical syntax parts in vfp, in prg code class code you use Dimension again, whereas in object.addproperty("aMyNewArrayProperty[3]" [, ValueforAllNewElements)
    method plus the addproperty function with the object as first parameter.indicating dimensionality inside property name string is enough.
    Here I wonder if it is enough to have a Clipper ragged array as last parameter on a undimensioned property name, but see no obstacles, as
    obj.addproperty("PropertyName", createobject("MyWishedforClass")) adds complex property, which could be the ragged type

    robert wrote: So would it be OK with you if the Dimension and Declare statements produce a FoxPro compatible array (as well as functions like ADatabases).
    And a declaration like

    LOCAL myArray AS ARRAY
    or
    VAR myArray := {1,2,3}
    would then produce a Clipper compatible array, that can grow with functions such as AAdd()

    gets also strong yes, perhaps with new keyword RAGGEDARRAY to register when speedreading code - as long as previously written vfp code works as expected, having more code options is a benefit. Would the vartype(RaggedArray)/type("RaggedArray") be "O" with further checking the object or a new return value like "R" ? Checking Alen() probably could not differentiate between vfp and RAGGEDARRAY ?

    How common is this kind of code (like the example from the help file) in your code? Would it be a problem to require people to declare the private first. We can add the @ character automatically in the compiler. We already have support for that.

    If it is a problem to require people to declare the variable first then it would also be possible to mark functions such as ADatabase() with a special attribute in the runtime, so the compiler "knows" that this is a function that may create a new local and then it can automatically generate a private (or local) declaration at compile time.


    On 11) I think I wrote a simple Try Catch when topic was raised a few months back which will handle creation of non-existing variable without heavy lifting, can en passant check that any existing variable really is a vfp array and otherwise throw error - Adding automatic @ / ref parameter after parse as not in vfp code for first parameter should be easy.in same step.
    If every vfp Array function is automatically wrapped with that Try Catch no real speed or other problems should crop up...

    edit: rethinking a bit, as 1. parameter is a reference, perhaps not even try-catch is needed if the macrocompiler works without failure if encountering lines along
    lnLines  =  ALINES(&tcMak, "1,2,3,5",5,",")
    where tcMak might be a string parameter the compiler cannot parse in advance, as checking only is done on globals, privates and locals in that scope defined by function or method.
    /edit

    regards
    thomas

    Please Log in or Create an account to join the conversation.

    Last edit: by mainhatten.
    • Page:
    • 1