[End of post moved to the beginning]
Axel Liljencrantz wrote:
On 1/3/06, *Netocrat* <[EMAIL PROTECTED]> wrote:
[when using a combined hash/array datatype, how are string and integer
indexes treated?]
String "1" is equivalent to integer 1 (in a shell the difference is not
very pronounced anyhow); both are a key that maps to a value. If
treating the hash as an array, conceptually that key is the first
element, but practically (internal representation) it could be located
anywhere. Where's the problem?
The problem that I can see is all the potential inconsistency when
silently moving from array to map.
[I've converted prompts from ">" to "fish> " to prevent quoting display
problems]
fish> #create array
fish> set arr foo bar baz
fish> echo $arr
foo bar baz
fish> #Use it as a map
fish> set arr[smurf] blue
fish> echo $arr
1 2 3 smurf
Not 100% intuitive, IMO.
Agreed; I've instead been envisaging it as:
fish> echo $arr
foo bar baz blue
to be compatible with current array semantics. Then I'm suggesting that
a get-keys operator (e.g. @), would result in what you wrote above:
fish> echo @arr
1 2 3 smurf
So "echo [EMAIL PROTECTED]" would have the same output as "echo $arr".
John's response to Axel's example was bafflement, and he writes:
I must not really understand Netocrat's suggestion at all
to which I say: as far as I can tell your understanding is correct.
[using [] as indexing operators for a combined hash/array data type and
thus avoiding a new type as well as being backwards compatible with
existing fish arrays]
That is indeed the main advantage of the [] map syntax. And it is a very
important one, what with my obsession with small syntaxes. :)
On the other hand, the {} map syntax also has some advantages.
* No potentially weird/unintuitive corner cases when creating an array
and converting it to a map
Responded to further down.
* No issues with exporting variables to other programs
Would you accept a rephrasing as "No additional issues..."?
* Easy to implement
Agreed, a naive (i.e. non-indexed) implementation is easy.
Do you want fish to support indexed hashes? If so, then a combined
hash/array data type is actually easier - John's suggestion implies
additional synchronisation/mapping issues: duplicate "keys" are possible
in the array representation of the hash but the array=>hash=>array
conversion must preserve array indexes for sane use. Since drafting
this post I've read John's response, in which he acknowledges this
problem and suggests a solution:
Of course you don't have to promise that the
original semantics will be preserved, which would solve that problem
at, I think, a fairly minor cost, since most users probably won't
be using the same variable both ways anyway. But it would be
conceptually nice if the naive semantics could be preserved.
Sure, that works, but by writing "most users probably won't be using the
same variable both ways" you seem to be acknowledging what I wrote
previously - that this is an infrequently used mapping. So when using
indexed hashes, there's no reason to retain the mapping given that it
results in "broken promises" - you might as well have two separate
datatypes, array and hash. And in that case, the consolidation offered
by the combination type is compelling given that it's possible to design
such a type without loss of hash or array functionality, as detailed below.
[much snippage, then...
echo $a where $a is a "sparse array"]
The 'missing' elements become empty elements, i.e. each one of them
contains the empty string.
OK, so actually sparse arrays /aren't/ supported by fish, contrary to
the claim in my previous post. "count $sparsearray" includes the
"missing" elements. Also, explicitly deleting an element shifts all
later elements towards the beginning.
This, John has elsewhere responded, is expected behaviour for an array
but not for a hash. So first let's see how easy it is to make the
current fish array more hash-like in this regard:
Introduce an "unset" symbol for fish's internal representation (in
addition to ARRAY_SEP) to differentiate between unset and empty elements
(a past list discussion touched on this subject). So we would have:
fish > set -e arr
fish > set arr[10] tenth_el
fish > count $arr
1
fish > echo $arr
tenth_el
fish > echo $arr[9]
fish: Array element at that index is not set
echo $arr[9]
^
fish > echo $arr[10]
tenth_el
fish > set arr[9] ""
fish > count $arr
2
fish > echo $arr
tenth_el # leading space intended
fish > echo $arr[9]
fish > set -e arr[9]
fish > count $arr
1
fish > echo $arr[10]
tenth_el
fish > echo $arr[9]
fish: Array element at that index is not set
echo $arr[9]
^
If introducing a combined hash/array type, the error message terms would
have alternate wordings: "array element" could also be "map value" or
"hash value", and "index" could also be "key".
Elsewhere John's suggested a default value for unset array variables,
which would work fine using the above scheme - fish would simply
translate the internal "unset" token into the user's default value on
expanding/accessing an array. For a combination hash/array datatype
this would work in the same manner from a user-perspective (ignoring
internal representation for now) and it would simply have no effect on
non-integral indices.
John's also defended the current "shift-on-delete" array behaviour:
set $a[1] foo
set $a[2] bar
set $a[3] baz
If you are setting array elements you expect one kind of behavior,
e.g., that if you delete $a[1] then $a[3] becomes undefined, while
$a[1] and $a[2] still exist, but with different values.
OTOH, if you were setting hash elements you would expect a different
behavior: deleting $a[1] would make $a[1] undefined, while $a[2]
and $a[3] still both exist, with their values unchanged.
This is a reasonable argument, because the shift behaviour is useful for
implementing fifos. To support it under the dual hash/array variable
type, I'd suggest two versions of "set -e" - one that behaves in the
"hash" style, and one that behaves in the "array-shift-for-fifos" style
where possible - i.e. it decrements the value of the index/key for all
immediately consecutive integer indices. So following on from the
example above:
fish> set a[10] notconsecutive
fish> set a[foo] notevenconsideredforshifting
fish> set --unset-array-shift-style a[1]
fish> echo $a[1]
bar # shifted
fish> echo $a[2]
baz # shifted
fish> echo $a[10]
notconsecutive # not shifted
fish> echo $a[foo]
notevenconsideredforshifting
So that covers all of the corner cases that immediately come to mind -
if anyone can see any others I'm interested to know.
--
http://members.dodo.com.au/~netocrat
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
Fish-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/fish-users