John Brock wrote:
On Tue, Dec 27, 2005 at 12:53:19PM +1100, Netocrat wrote:
John Brock wrote in a message he forwarded:
[...]
My suggestion is that by using a different syntax you can always
look at any array as a hash.
[and vice versa, by mapping a hash to a sequential list as key1, value1, key2, value2, ...]

A hash datatype requires a new operator to access the hash keys (so afaics it's possible to avoid different braces per Axel's preference, but /something/ new has to be added). John's idea of two indexing bracing styles achieves this, but interspersing the hash values with the keys as part of a get-keys operator is redundant.

Another possible get-keys operator is a modified prefix, e.g. @ rather than $ - so @hash[1] would return the first key and @hash[count $hash] would return the last. This has the advantage of being able to access the entire key list using @hash, which can be passed as an argument to a for loop or to echo or printf. The alternative indexing operator could achieve this through something like {*} for all values and [EMAIL PROTECTED] for all keys, but this is less intuitive and not backward-compatible with existing syntax, since $hash unadorned would return keys as well as values.

IME the mapping that John describes is rarely used. So supporting it in the get-keys operator doesn't warrant the inconvenience of having only odd-index access to the list of hash keys, and losing backward compatibility with the meaning of unadorned $array.

In Perl if you assign a hash to an array you get alternating keys
and values, which is where I got this idea.  The additional thought
that occurred to me was that there was really no reason why you
needed two data types with two namespaces -- that in fact you could
use a single data type both ways.  This just seems simpler to me.
Why multiply entities if you don't have to?

Exactly. And the PHP-equivalent alternative avoids multiple entities. It's simpler than Perl's hash/array duality. Your proposal retains multiple entities - a hash (using {}) and an array (using []). Regardless that /internally/ you propose these be stored in a common format, from the user's perspective they are mappings between two different data types. I've pointed out that your hash model could be used identically to our current proposal, meaning that your hash=>array mapping index operator (using [], although for backwards compatibility the meaning of your [] and {} operators would need to be reversed) is an "optional extra", but you don't seem to recognise it.

I don't see how doing this is redundant -- it's just an alternative

Because the main new operation required on a hash is "get keys". Your scheme allows this, but rather than "get keys", it only supports "get keys with values interspersed". Yes, you could take care of this using odd-only indexing, but why complicate code that doesn't need to be complicated?

way of looking at a list -- and in particular I don't see how you
lose backwards compatibility with the original meaning of an array.
Anything you could do before with a variable you can still do --
it's just that you've just been given some new syntax that lets
you do some new things with a variable that you couldn't do before
(i.e., look up the values of even elements based on the values of
odd elements).  In practice a user would normally use a particular
variable one way or the other,

Right, and that's my point - it's an infrequently used mapping that doesn't require operator-level support.

but all operations on any variable
would always make sense and yield reasonably reasonable results.
(Note that if you wanted to iterate through all the keys or values
you could just increment your loop counter by 2 instead of 1 --
although maybe you would also want special functions for extracting
all the keys or values, again like Perl).  Some things that one

Those special functions are frequent enough to warrant an operator, whereas the mapping you propose is infrequently used enough to be implemented as a function instead.

might reasonably do with an array -- such as deleting a single
element -- would totally redefine the hash lookup.  But as the joke
goes, if it hurts when you do that, then don't do that!

I'm less optimistic about one thing though.  Originally I thought
that the hash lookup could at first be implemented by just searching
an array from beginning to end for a key (which would be a fast
and easy thing to do), and then at some later date something more
sophisticated could be done by attaching indexes to a variable the
first time it was used as a hash, without changing the semantics
(i.e., the array values would not be scrambled when you used a
variable as a hash).  I assumed there was some way to do this was
at least reasonably efficient, even if you didn't end up with the
the most highly optimized hashes on the market.  But I'm not so
sure any more, and I suspect that if you want even moderately
efficient hashes you are going to have to accept that using a
variable as a hash scrambles the array in some way.  Logically this
isn't necessary, but in practice it may be, and it detracts from
the prettiness of the scheme.

I noticed something similar but didn't want to focus on it in my last response. Assuming that an index is used, and that the structure is initially treated as a hash, then when mapping from hash to array, how is order determined? Alphabetically? By time-of-insertion? By internal index order? The answers can be specified, but they're not necessarily going to be intuitive.

I still think it's a good idea
though; it gives you all the power of Perl hashes, with only one
variable type and namespace.

Or almost all the power.  Does fish support sparse arrays?  I.e.,
can you:

set a[1] Hello
set a[1000] Goodbye

and then use a[500] and a[1500] (returning the value "")?

Did you try it?

Yes, it does, but the missing empty elements are space-separated on expansion. Last I looked at the source, fish would internally be storing 999 ARRAY_SEP characters for the missing elements.

[...]

The advantage to all this is that you don't have to introduce a
new data type for hashes,

PHP supports a similar data type to that previously discussed on this list - an array that may be indexed traditionally (numeric keys) or as a hash aka map (string keys) using the same indexing operators []. This seems to be compatible with the model John suggests for the hash indexing operators {}.

But what if you want to use "1" as a hash key?  Either you need

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?

some kind of new systax, or you have to accept that some strings
cannot be used as hash keys.  I think the former is preferable.

--
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

Reply via email to