"guarded" fetch from hashed array



Dear Edd Barrett,

I'm afraid you've come across one of the ugliest parts of Maxima.

There are actually *two distinct kinds* of associative array in Maxima:
"hashed" associative arrays (which you get without declarations), and
"hash_table" associative arrays (which you get with make_array('hashed)).
 Bizarrely and inexcusably, the semantics of these two kinds of arrays are
completely inconsistent.

The "hash_table" style is problematic in various ways and I would recommend
it be rethought and replaced.

In the meantime, though, you can define the following:

:lisp (defun $hash_table_defined (ar i) (multiple-value-bind (val ok)
(marrayref-gensub ar i nil) ok))

Then hash_table_defined( <<hash_table>>, <<index>> ) will return true or
false.

A simpler way to do this is just to make sure that FALSE is never a valid
value.  Since you are storing lists of variables, how can FALSE ever be
valid?

                 -s

For example:

*Hashed style*
qq[3]: 5$
qq[3] => 5        OK
qq[7] => qq[7]
qq => qq         << treated as an identifier, not as a first-class value
kill(qq[3])    OK
qq[3] => qq[3]  restored to uninitialized state
arrayinfo(qq) => [hashed,1,[3]]
qq[5,5]: 999 => error  -- must have consistent number of subscripts


*Hash_table style*
rr: make_array('hashed)$
rr[3]:5$
rr[3] => 5      OK
rr[7] =>  false    <<< inconsistent
rr => {Lisp Array: #<hash-table 10d2408c>} << treated as a weird internal
object
kill(rr[3]) => error
arrayinfo(rr) => [hash_table,1,3]   << notice inconsistent conventions
rr[5,5]: 999   => no error -- allows different numbers of subscripts
arrayinfo(rr) => fatal error (implementation bug)