Follow-up to : trying to use "get" inside a Maxima function - problem using hashed arrays (FYI)



Recap : my original goal was to attach a "quality" to a variable that has a value, so that when the variable was passed to a function, the function could take the appropriate steps based on the quality.  In particular, I'm trying to add to the CTensor package functionality, which requires knowing whether a tensor has upper and/or lower indices.  My goal is to be able to manipulate vectors, matrices, and arrays containing equations in order to multiply tensors, take the covariant derivative of them, raise/lower indices, etc.

I have since found a problem with using hashed arrays.  The following code
------------------------------
kill(all)$

test_ll[val]:matrix([1,2],[2,1])$
test_ll[rank]:'Trank2LL$
print("Made in-line : ")$
test_ll;
properties(test_ll);
arrayinfo(test_ll);
test_ll[val];
test_ll[rank];

MakeTensor():=block([temp], temp[val]:matrix([5,5],[5,5]), temp[rank]:'Trank2UU, temp)$
test_uu:MakeTensor()$
print("Made by function : ")$
test_uu;
properties(test_uu);
arrayinfo(test_uu);
test_uu[val];
test_uu[rank];
------------------------------
Produces the following output :

Made in-line :  
                                                  test_ll
                                              [hashed array]
                                        [hashed, 1, [rank], [val]]

                                                 [ 1  2 ]
                                                 [      ]
                                                 [ 2  1 ]

                                                 Trank2LL
Made by function :  
                                                   temp
                                                  [value]
arrayinfo: test_uu is not an array.  -- an error. To debug this try: debugmode(true);

                                                 [ 5  5 ]
                                                 [      ]
                                                 [ 5  5 ]

                                                 Trank2UU
------------------------------
Note in particular that despite the fact that the [val] and [rank] values are correct, the variable made by the MakeTensor function is NOT a hashed array, and has a "name" (sorry, I don't know all the Maxima terminology yet) of 'temp' instead of 'test_uu'.  The following variations on MakeTensor made no difference : 
    MakeTensor():=block([temp,rank,val], temp[val]:matrix([5,5],[5,5]), temp[rank]:'Trank2UU, temp)$
    MakeTensor():=block([temp], temp['val]:matrix([5,5],[5,5]), temp['rank]:'Trank2UU, temp)$

This causes problems when a variable from MakeTensor is passed to a function that takes a tensor as an argument and returns a tensor : 
------------------------------
Convert(T):=block([temp], temp[val]:T[val]-1, temp[rank]:'Trank2UL, temp)$
test_ul:Convert(test_uu)$
test_ul[val];
test_ul[rank];
test_uu[val];
test_uu[rank];
------------------------------
Resulting in :
   [ 4  4 ]
   [      ]
   [ 4  4 ]

   Trank2UL

   [ 4  4 ]
   [      ]
   [ 4  4 ]

   Trank2UL
------------------------------
Because test_uu's "name" is 'temp', its [rank] and [val] values ALSO GET CHANGED!!!  

I can think of several potential work-arounds, such as declaring the variables globally, or using different local variable names inside the functions, but none of these can provide the functionality, ease-of-use, and guaranteed error-free performance that I want.

However, I have tried all of the above with the (undocumented) "defstruct" feature (examples in my previous email), and it has none of these problems.  It also avoids any potential problems should the user assign values to the symbols 'val' or 'rank'.

Unless someone knows a quick and easy fix to the hashed-array method, it appears that defstruct is the only way to go.

I just wanted to pass this information along so others wouldn't get bitten by the same problem.

Bruce