REBOL 3.0

Comments on: Change the Hash Datatype in 3.0?

Carl Sassenrath, CTO
REBOL Technologies
28-Nov-2006 17:16 GMT

Article #0052
Main page || Index || Prior Article [0051] || Next Article [0053] || 52 Comments || Send feedback

It has come time to decide if we want to change the hash datatype for REBOL 3.0.

As you know, the hash datatype is implemented as a special type of block that can also be accessed with hash keys. It is quite powerful, but it is a little odd for many users, especially for those who think it should work like the dictionaries found in other languages.

So, what do we want to do about hash? Now is the time to make changes.

Current Behavior

Let's start with a simple set of examples of how hash works:

As you know, you can create a new hash with:

where: make hash! 100

Then, you can add some keys and values with code such as:

append where [bob   "Ukiah"]
append where [mary "Eureka"]

Or, you could create the hash directly from the block with:

where: make hash! [bob "Ukiah" mary "Eureka"]

Now, you can use key values to select content values with code such as:

probe select where 'bob
"Ukiah"
probe where/mary
"Eureka"

And, because hash types also act as blocks, you can do block operations too:

1. Pick keys and content values by index position:

probe pick where 3
mary

2. Change keys or content using block functions:

change find where 'mary 'linda

3. Iterate over a hash as a block:

foreach [key value] where [print [key value]]
bob Ukiah
linda Eureka

4. Easily convert back to a block:

probe to-block where
[bob "Ukiah" linda "Eureka"]

5. Serialize (mold) the hash dictionary:

probe mold where
{make hash! [bob "Ukiah" linda "Eureka"]}

And, there are many more... too many to show here.

Those are useful features, don't you think? Accessing hashes as blocks is a powerful feature.

What's Wrong?

So, what's wrong with REBOL hashes as dictionaries? I can imagine these items could be the main issues people think need to be corrected:

1. All values are keys, even the content values.

Another way to say this is: hashes are not key-value paired (no skip 2 relationship). Everything is hashed.

Here is an example that uses a content value as a key:

probe select where "Ukiah"
linda

This becomes a problem if your keys and your content both use the same datatype (e.g. strings) and can include the same values. For example, if you are using a hash to convert English to French, it would be a problem. (Because French and English share many of the same words, but not the same translations.)

2. You cannot use keys directly as indices.

For example, you cannot write:

pick where 'mary

poke where 'mary "Willits"

That's because pick and poke expect numeric indices to address the block part of the hash type.

3. You cannot add new values using the key value assignment form.

That is, you cannot write:

where/tom: "Willits"

because 'tom is not part of the hash block.

4. You have no control over case-sensitivity for hashes.

select unix-cmds "cd"

select unix-cmds "CD"

These produce the same results.

What to do?

So, what do we want to do about it? We are at a point where we need to finalize the hash datatype for REBOL 3.0. It is possible to make some changes.

Speak now, or forever hold your peace.

52 Comments

Comments:

Gregg Irwin
28-Nov-2006 13:14:02
You can get a LOT of leverage out of the associative array/dictionary model from other languages (wasn't AWK a pioneer here?). It's something I miss, and my mezz versions just aren't as clean as a native syntax would be (even when done as a dialect). I can't say as I've ever been able to leverage hash! to its full extent the way it is now, which is a shame. I don't know how much code would break, or if it's a viable option to create a dictionary! type for this purpose, so as not to break hash!.

I'm not sure how many people new to REBOL realize that SELECT does *not* operate on a skip/2 basis, because the dictionary model is so prevalent in people's minds.

Much as it might be risky to break some code, I think the value of a more standard idiom here would outweigh the pain it would cause, and I would vote for the change.

Carl Sassenrath
28-Nov-2006 13:23:22
Thanks for the quick input Gregg!

Yes, one way would be to leave hash! as is and add a new dictionary! type (or is there a better (shorter) name?)

It might even be possible to share 90% of the same implementation code, so not to significantly expand REBOL's footprint with this addition.

And finally, what syntactic format would you want that makes it feel more comfortable? Paths? (We would need to keep it within the REBOL lexical domain.)

Carl Sassenrath
28-Nov-2006 13:34:33
Also, tell me what you think it should look like. For example, is this enough (adds both key and content):

city/bob: "Ukiah"
city/tom: "Willits"
city/ken: "Mendocino"

Note: If you want to show examples here... just surround them with the html pre tag.

Carl Sassenrath
28-Nov-2006 14:00:43
Let's compare the basics with Python Dictionary Format.

Notation: P for Python syntax. R for same thing in REBOL.

P> tel = {'jack': 4098, 'sape': 4139}

R> tel: dict [jack 4098 sape 4139] ; note 1
P> tel['guido'] = 4127
R> tel/guido: 4127
P> tel['jack']
4098
R> tel/jack
4098
P> del tel['sape']
R> remove find tel 'sape ; note 2
P> tel.keys()
['guido', 'irv', 'jack']
R> first tel ;note 3
[guido irv jack]
P> if tel.has_key('guido') ...
R> if find tel 'guido ...

Notes:

1. Assumes DICT defined as a mezz constructor (similar to FUNC). Also, shows words for keys, but they could be anything else (strings, numbers, etc.)

2. There is no shorthand for delete.

3. This depends on if we still want to allow indexing on dictionaries. If so, we will need another method.

Henrik
28-Nov-2006 14:03:55
I don't know much about the use of dictionaries, but select could be equipped with a /key refinement if you specifically want the key:

>> select dict bob
== "Ukiah"
>> select/key dict "Ukiah"
== bob
>> select/key dict bob
== none

But it would then cause a little problem that would make select inconsistent with R2, unless used on a specific dictionary! datatype:

>> select dict "Ukiah"
== none

I'm not sure, but I think one should think about two scenarios when designing this: One where you specifically want the key or the value or the other where you just want to get the counterpart, regardless of input.

Carl Sassenrath
28-Nov-2006 14:18:44
Another question:

Should we also consider a direct lexical format for this datatype? (Not just a functional constructor or mold/all format).

##[jack 4098 sape 4139]

I should note that this is consistent with REBOL unicode! datatype's lexically encoded format:

##{blahblahblah}
Carl Sassenrath
28-Nov-2006 14:22:44
Note that I am caving-in to user demand here...

Why? Because hashes/dictionaries have no value in REBOL for small sizes... because you might as well use blocks when the datasets are small. They take less space and for small sets are faster (no hashing time).

Huayin Wang
28-Nov-2006 16:11:59
How fast is the key lookup implemented for the current rebol hash? I used a lot of python dictionary partly because of its fast key lookup.
Carl Sassenrath
28-Nov-2006 17:18:22
Hash key lookup is hundreds of times faster than block access methods. In this hash example I show it being 650 times faster.
Ryan Cole
28-Nov-2006 17:19:04
How about we add a function that is used to update/append values, since we dont have an efficient way to do that. I have something I use with blocks, and it definately simplifies and reduces code. Perhaps use something like it that works with both blocks and hashes.

I have tried a few variations, my favorite is cite/recite. Cite takes block, name, and value, and updates the value or appends it to the block. Recite is basically select/skip ... 2, which is not necessary for hashes, but a cleaner shortcut for blocks.

(My real preference is to have a way to update/append with path type referencing, but appearently this is asking too much.)

Scot
28-Nov-2006 17:28:13
How does this relate to the inclusion of a good database as part of REBOL? Could a more dictionary like hash be used instead? How would a more robust hash relate to SQL Lite for instance?
Ashley
28-Nov-2006 17:49:05
How often are hash! (and list!) actually used? I've looked at all my scripts and every script I've downloaded from REBOL.org and can't find a single instance of either.

Where I have needed hash! type functionality I've used mezz wrappers around blocks (e.g. a binary search wrapper) to give me the exact result(s) I want, and faster than using hash! anyway.

So my vote would be to remove the hash! (and list!) datatypes and provide native! and mezz wrappers for alternate access methods. I'd rather see more time spent making block! the best generic container type it can be than trying to define and implement specific container types for the 5% (if that) usage case.

Ladislav
28-Nov-2006 18:03:49
I used HASH! only to implement a few dictionaries yet, although I know it can be used in more complicated cases too.
Goldevil
28-Nov-2006 18:04:43
I use hash datatype often.

I agree with Scot, about the relationship between hash! and databases. Usually I use hash! to store data that comes from a database. It's just more convienient and goes faster than sql queries when I need running complex manipulations on it. Sometimes I use a par of hash! to store key and values. In fact I create a kind of custom dictionnary.

I do not have a real preference for the way to implement a dictionnary. I just think it's very usefull but I want a backward compatibility (if possible) with rebol 2.x

Alc
28-Nov-2006 18:32:37
Also agree with Scot.

I also wonder if an enhaced hashes may have some relation with the eventual addition of REBOL Indexed Files (RIF)

Maxim Olivier-Adlhoch
28-Nov-2006 19:05:27
having used python extensively in corporate environment, I daresay that the dictionary datatype in python is very usefull. and very used. its the basis of many virtualised object accessors and is extremely fast IIRC.

it also gives a simple way to index data, and is clearly an expressive advantage within the language.

unfortunately, in REBOL, IMHO the hash! type makes little sense because it does not give an expressive advantage over block!. and for any really large dataset, we'll use a real database anyways... so its hard to give it a real use.

result, as Ashley points out its virtually unused as-is.

Carl Sassenrath
28-Nov-2006 19:09:23
Those are good points. Thanks.

I have only used hash! 3 or 4 times over the last 6 years. It was always for DB purposes, such as the IOS server file tracking (e.g. usage with 60,000 files), or tcp address comparisons, etc. But, in all cases a little DB engine (if it were internal to REBOL) would have been better due to the high overhead of loading/saving the entire database.

And, I don't recall ever using list! So, that is a candidate for removal.

It turns out, to this point, I have left hash! and list! out of 3.0. Which is the reason I am currently hashing this around (forgive the pun).

However, the difference, unique, union, intersect, and exclude functions require the hash! datatype to achieve log(n) and not n**2 performance on large sets. Of course, we can find other ways to do that.

Scot
28-Nov-2006 19:29:39
As long as something like RIF or SQL Lite libraries or such are included, or the mezz wrappers suggested by Ashley, I think list! and hash! can go.
Scot
28-Nov-2006 19:30:55
How about a good associative database so we can simply obviate the problem altogether? :0)
Carl Sassenrath
28-Nov-2006 19:53:06
I should mention that while I was waiting for comments to this blog, I ported the hash datatype from 2.7 (BTW, it adds 4K to REBOL).

Also, I should say that it concerns me just a bit that Python, Ruby, Perl, et. al. all provide a "dictionary" collection, and they consider them important! However,... in REBOL that approach is rarely used due to the flexible concept of blocks themselves.

Brian Tiffin
28-Nov-2006 21:04:28
Christmas wishing. Keep hash! add hashed key map! (or dictionary!)

Carl; have a little fun making up a key/value pair datatype that will no doubt rock, leave a sense of familiarity for new users and add yet another reason to evangelize.

Ryan Cole
28-Nov-2006 23:40:17
if were getting a DB, I say slash hashes. The more I thought about it, the associative array feature of hashes has never worked out well for me, something always seems to not like it. I do like proposed changes, but odds are I would use my update/append (cite) function with blocks because its more flexible and predictable (for me).

Ron Hochsprung
28-Nov-2006 23:45:26
I build quick-and-dirty assemblers and mini-compilers, and find the use of hash tables (i.e., associatively indexed "arrays") quite natural for symbol tables, etc. The lack of the distinction of "key" vs "data" that exists with Rebol blocks is counterintuitive when one comes from a Perl or Python legacy.

I think that "hash" inclusion in Python, Perl, Ruby, etc. is a hint that the concept has been proven useful.

-pekr-
29-Nov-2006 1:28:20
Do we need to remove them? Not for the compatibility sake, but because new users might look for them? And as you said - you need them internally anyway, right?

I would like to hear Ashley elaborate a bit, what do he mean by:

"So my vote would be to remove the hash! (and list!) datatypes and provide native! and mezz wrappers for alternate access methods. I'd rather see more time spent making block! the best generic container type it can be than trying to define and implement specific container types for the 5% (if that) usage case."

As for RIF and eventual SQLite inclusion in Rebol kernel - we would have to know more about them. What if you need fast lookup, but DB is an overkill (e.g. already mentione symbol tables lookups, tcp adress comparisons etc.)?

Gregg Irwin
29-Nov-2006 1:32:55
As far as hash! and list! being used, I think it's rare; not unheard of, but rare. When I first found REBOL, I thought the consistent interface to all block values was something I would leverage--use blocks to start, then just convert to list! or hash! if I found I needed their behavior, and no other code would need to change. The problem is that their behavior is slightly different, and there were some old bugs, so I never did that. The main reason is probably that blocks are just fine 99.71% of the time. I've used hashes just a few times, for the same reason others mentioned.
Gregg Irwin
29-Nov-2006 2:10:53
The benefits of making it a datatype with special semantics is that the interface is concise, and consistent with other series, though things like ordinals and PICK/POKE have to be considered, as Carl mentioned. It looks "built-in", and that's a good thing.

Path notation seems great at first glance, but if you look at the idioms, we would probably be using paren-path notation quite a lot, because your keys are often unknown; is that better than just using a few mezz's?

    hash/(key): value
    value: hash/(key)
    remove find hash key
    found? find hash key

versus:

    set-key hash key value
    value: get-key hash key
    remove-key hash key
    has-key? hash key

In the cases where you're keys are known--e.g. small lookup tables--you can just use a block if you know that values won't conflict with keys, giving us a lot of what other langs use them for.

If we have a specific datatype, that means more "hidden" behavior--syntax that looks the same on the surface, but works differently based on the datatype. If we use a few simple mezzanines, it can work on any series so you can still decide if you want to use a hash! or a block!.

The main things it does are: 1) handles the /skip 2 detail (and could have a /skip refinement as well), and 2) automatically adds items if necessary.

As mezzanines (or new natives), it fits well with REBOL, can be consistent within that group of associated funcs, and is easy to implement and understand. If you want the keys, you can just use EXTRACT.

Marco (Coccinelle)
29-Nov-2006 2:18:21
The reason why I have never use list! is that the behavior of list is different from block :
>> block: make block! []
== []
>> insert block "a"
== []
>> block
== ["a"]
>> list: make list! []
== make list! []
>> insert list "a"
== make list! []
>> list
== make list! []

Except that, leave hash! datatype as it is and add a new datatype map! or dictionnary!

Marco.

Ryan Cole
29-Nov-2006 2:49:15
And consider automatically adding new values:
either found? hash/(key) [
    hash/(key): value
][
    repend hash [key value]
]
versus:
set-key hash key value
Maxim Olivier-Adlhoch
29-Nov-2006 3:27:13
somewhere a post of mine was not done!

Why not use the interface of object! instead of block for access to hash! types?

quick example:

keys: first hash 

foreach key keys [print hash/:key]

hash/akey: 666

>> third hash == [akey: 666]

or would words be too restrictive as keys?

Oldes
29-Nov-2006 5:54:08
I found hash! useful in the past. Not so often, but it was nice to have it as it's much more faster then block! in some cases. Don't know if it's good to remove it. But I can imagine to live without it, if there will be some easy and fast way how to deal with really large blocks of data (native Rebol database). I don't care if current hash! has some limits, it was working for the case I needed, so it's fine.
Oldes
29-Nov-2006 6:12:01
And if you want an example from the recent time... I used it to count word frequencies in books. It would be almost useless if I would have to use just a block!. With the hash! it was pretty easy, just a few lines of code, no need for heavy databases. If no one else, I would miss the hash!
Cyphre
29-Nov-2006 6:47:45
I would either add native dictionary and remove hash! or leave hash! as is. I found it useful for large data manipulation in terms of performance.
Norm
29-Nov-2006 12:31:56
For me, the dictionary or symbol lookup table problem begs for the n-tuple datatype. Separate the question of datatype from the problem of efficiency of sorting data.

1. Need of a n-ordered tuple datatype, as unobtrusivily notated as the block, with its own operations

As well as a block could be viewed as a set, an unordered pair, with the difference, unique, union, intersect, and exclude functions, there could be the ordered n-tuple as a native datatype. The n-tuple could serve as relationships, directed graphs, linguistics predicates, and be compounded in cartesian products, powers, etc, depending of the datatype of its terms. So we could have not only the pair (somewhat envisioned in the hash), but also any consecutive ordered suite of given (small) length, say from 0 to 99 arity (number of terms). We, then, could have a block of n-tuples and tuples of blocks.

Notation wise, it should be kept simple, as the block is. But there is the difficulty of having an intuitive notation method to specify the nomber of the arity. The tag, < >, popularised in html and xml, is, some could see it so, a tuple with some terms not always specified.

If we choose the basic tuple as the tag <> (for the sake of this discussion), then the nil-tuple would be the empty tag <> (no name no value), the 1-tuple would be the left empty tag (which would be easily convertible to a block of the values), the 2-tuple would be the pair, the 3 tuple would be the triple, and so forth up to a reasonable arity length of (for discussion purpose) 99 (two digits).

A dictionary would be a list (block) of n-tuples sorted of the first term of the tuples, regardless of their varying arities. The first term would be presumed a name, in the sense that some operations like sorting would apply to it.

Norm
29-Nov-2006 12:32:52
2. Make the jazzed array possible

The jazzed array should not be banned by unnecessary constraints on the spec of the n-tuple data aggregation. The block

a: [
	<04 Doe John "123 Riviera St." Toronado>
	<03 Big John "New York">
	<02 Jeck Thomas>
]
should be possible.

With the structure of an n-ordered tuple, we could formaly have the operations of relationships, functions, cartesian products and powers, depending on the datatypes of the terms.

Norm
29-Nov-2006 12:33:44
3. Make it adressable by name

The first term being also presumed a name key (it could be), it would serve directly as indice, instead of only rank number of aggregated tuples. Intuitive add, remove, sort methods could be provided to be easily accessible to newcommers (to thin the learning curve).

In Rebol an object is more than that, and a block is less than that (set or unordered tuple).

That gap needs to be filled, with a notation that is as unobtrusive and as intuitive as the block.

4. Tap it to the rest

The rest follows from that, sorting, efficiency, storage. A tuple could be a container to interim data to be stored to a database, or to a file structure.

Maybe we could simply have a notation to give an orientation and arity to the block, which would give it more syntactic scope, like [06> <06], that would be an easy read [ [02> A B <02] ] discernible from [04> [a b c] [A B C D] [John Doe] [] <04].

The question of case sensitivity could be managed in the sort functions, as well as enhance the sort order for the main localised foreign languages (at least those enabled by the 8 bit char set : French, etc, instead of only Ascii.) : sort/casesensitive/descending/french.

As said, such a datatype could easily serve as the interface to permanent storage structures, as database and Rif.

Gregg Irwin
29-Nov-2006 13:00:03
Ryan, SET-KEY would do the auto add-or-update logic internally, so you never have to worry about that.

Using tags as a block type doesn't seem like a good fit, since tags are strings today.

The more I've thought about this, the more I think the mezz approach might be best, though not necessarily with the names I used here. What would be the biggest reason(s) you can think of not to go that route?

Gregg Irwin
29-Nov-2006 13:11:31
One of the big questions is whether to auto-create items when you ask for them, giving them a default value of NONE. It's easy and natural to return NONE if the key doesn't exist, but does asking for an item create a slot for it, so the block is populated with slots for things you've asked for.
Gregg Irwin
29-Nov-2006 14:07:33
Sample implementation of proposed mezz funcs, so we can think about behavior goals, whatever the syntax ends up being.

    set-key: func [ ; insert-key, change-key ?
        {Updates a named value in a series of key-value pairs, appending the
        key and value if it doesn't already exist; returns the series head.}
        series [series!]
        key
        value
        /local pos
    ][
        either pos: find/only/skip series key 2 [
            head change/only next pos value
        ][
            repend series [:key :value]
        ]
    ]

get-key: func [ ; select-key ? {Gets a named value in a series of key-value pairs, or NONE if the key doesn't already exist.} series [series!] key ][ ; Auto-create a "slot" for the key if not find/only/skip series key 2 [repend series [:key none]] ; Have to get the first item, because /skip causes SELECT to ; return a block. first select/only/skip series key 2 ]

has-key?: func [ ; found-key? {Returns true if key exists in the series of key-value pairs; false otherwise} series [series!] key ][ found? find/only/skip series key 2 ]

remove-key: func [ {Removes a named value in a series of key-value pairs, or NONE if the key doesn't already exist.} series [series!] key /local res ][ ; What should this func return? REMOVE result, series head, the value ; at the key, or item removed--key+value? res: get-key series key remove/part find/only/skip series key 2 2 :res ]

Carl Sassenrath
29-Nov-2006 14:31:33
Thanks Gregg. As I look it over, I wonder if these can be embodied in the datatype methods themselves?

BTW: looks like there is a bug in the blogger formatter backend. Probably due to indented sections. If anyone has the fix, let me know. Sorry, I have no time right now to mess with it. Source code link is in the page footer.

Goldevil
29-Nov-2006 18:42:43
I wrote a contact management software in Rebol that allows to manage mailing list. The user can put contacts to a mailing list, merge mailing lists, sort a mailing list,...

These datas are stored in the MySQL database but the sofware needs to manage them in memory. If I use block! instead of hash!, the performance is so bad that the software becomes unusable. Some seconds become more than two minutes with a 5000 contacts / 10000 adresses database (a contact could have more than 1 address).

Is there a way to resolve the performance problem without hash type ?

Ashley
29-Nov-2006 19:39:27
%binary-search.r on REBOL.org is a good start.
Gregg Irwin
29-Nov-2006 19:40:48
It will be hard to give good advice without knowing more details.
Oldes
30-Nov-2006 3:50:18
Goldevil: I think so. You can do all the basic operations with hash.
>> h1: make hash! [a 1]
== make hash! [a 1]
>> h2: make hash! [a 1 b 2 c -1]
== make hash! [a 1 b 2 c -1]
>> h3: union h1 h2
== make hash! [a 1 b 2 c -1]
>> sort/skip/compare h3 2 2
== make hash! [c -1 a 1 b 2]
Goldevil
30-Nov-2006 5:05:38
What I want to explain is that hash is useful because you cannot always rely upon database access to manage indexed data.

SQL database or Rebol Index File is not a replacement for hash! or any new dictionary datatype. It's complementary. Accessing files or a remote database will never be equivalent to managing data in memory in term of performance.

In the software I mentionned, I load from database all IDs of contacts and their adresses and store it into hash! variables (one for all contacts, one for contacts inculded in a mailing list, another for contacts in another mailing list,...). Then the user can try some complex operations on the mailing lists.

I tried 3 solutions :

1) With hash! the process can takes some seconds

2) With block! the process can takes some minutes

3) If I build some complex SQL queries and send it to database, the execution takes less than 3 seconds inside MySQL but it takes more than 10 seconds for full process because the database is stored on a server on a heavy loaded network. The drawbacks : - Some manipulations are just temporary and I must work with temporary tables. Database is designed for persistence, not hash! - Building the SQL queries is more complex and takes many more lines of code than playing with rebol and is cool syntax (union,...)

I think that in this case, hash was the only good solution. It's simple, it's fast and it's 100% rebol.

I agree that hash! is used not very often but when it's used it's very useful.

I agree that hash is removed from rebol 3.0 but I wish another indexed datalist type, like a dictionary.

Sorry to explain the same thing again but I want to fight for hash!. Save hash! datatype! ;-)

Andreas Bolka
30-Nov-2006 10:09:14
Nice stuff, Gregg. Add the following to the mix:

extract-keys: func [
    {Extracts the keys in a series of key-value pairs.}
    series [series!]
][
    extract/index series 2 1 
]

extract-values: func [ {Extracts the values in a series of key-value pairs.} series [series!] ][ extract/index series 2 2 ]

And I'd rather not have GET-KEY automatically create a "slot" for a non-existing keys.

Gregg Irwin
30-Nov-2006 10:25:53
I agree that we should "save the hash!" Goldevil.

Andreas, yeah, that's one of those design ideas that has pros and cons. Another option is to have a refinement that allows you to specify a default value if the key doesn't exist, rather than returning none.

Is there a reason you used:

  extract/index series 2 1 

Rather than:

  extract series 2

Just for consistency with extract-values?

Andreas Bolka
30-Nov-2006 13:20:27
Yes Gregg, and I vastly prefer the default-value refinement. Especially when you sometimes want to retrieve all keys/all values, the automatic slot allocation results in what I consider quite unexpected results.

The

extract/index series 2 1
is really there for consistency reasons, trying to make obvious the duality between extract-keys and extract-values. Nevertheless, that's one of those situations where I'm not too sure wether I actually prefer the code this way or the other :)
Robert
1-Dec-2006 2:30:49
IMO it depends what we want to achieve:

1. Is speed the goal? Than it all comes down to use the right datastructure for your app. In this case it's very good to have a highly optimized hash! (working like a dictonary) datatype.

2. Is it simplicity of the language? Than it all comes down to use few simple concepts. Like the block! stuff. It's OK for most uses.

Carl, maybe you can create a transparent hash! that's used via block!. Maybe there is a heuristic, when to swap to a hash implementation internally without the user noticing it.

And I want to note some other things, we should think about in this context:

- Differences between object!, block!, and hash!? The access pattern looks quite similiar to me.

- FIRST, ... and PICK on series. PICK returns none! when nothing is found or the block! is empty. FIRST throws an error.

Ridcully
1-Dec-2006 5:04:46
I think there is a problem in the big picture of REBOL if you have to discuss all that stuff in order to create a new version of the language. In cases like this one can see the advantages of object oriented languages like JAVA or Ruby. There the Dictionary or (Hash)Map are simply Classes and not embedded in the language itself. In other words you could simply create a Dictionary class and probably discuss how that should work but it wouldn't prevent you of finishing REBOL 3. Infact anyone here could create the type of dictionary, hashmap or whatever (s)he likes and needs.
Gregg Irwin
1-Dec-2006 16:18:08
Robert, I think the ordinal funcs are already going to be updated not to throw errors.

Ridcully, this type of design discussion isn't a problem at all; it's part of what makes REBOL different, in that a *lot* of thought and effort goes into the things that are built in, because the payback in consistency and ease of use is huge. It doesn't mean you can't build your own, we do that all the time, but the power and elegance of REBOL--not to mention it's small size--comes from thinking long and hard about these kinds of issues, and building the right things in that provide the most value and expressive power.

That said, right now I'm leaning towards a mezzanine solution that fits your way of thinking. We don't have to change anything in order to use it, and it can be patched in to any version of REBOL quickly and easily. There's no syntactic sugar, which might be nice, but we can live without it if we have to. I'm still hoping for feedback on why *not* to go that direction.

Carl Sassenrath
2-Dec-2006 14:38:13
Thanks for the good input!

I'll now post a new blog with my thoughts.

Don Dwoske
10-Dec-2006 21:37:14
If no one else has suggested this : I think Lua has an excellent datatype called 'table'. It is a very flexible and general abstraction on several related concepts.

"We use tables to represent ordinary arrays, symbol tables, sets, records, queues, and other data structures, in a simple, uniform, and efficient way. Lua uses tables to represent packages as well."

http://www.lua.org/pil/2.5.html

The implementation is very fast, and usage is straightforward and very flexible. The table is the primary reason why I love Lua.

Post a Comment:

You can post a comment here. Keep it on-topic.

Name:

Blog id:

R3-0052


Comment:


 Note: HTML tags allowed for: b i u li ol ul font span div a p br pre tt blockquote
 
 

This is a technical blog related to the above topic. We reserve the right to remove comments that are off-topic, irrelevant links, advertisements, spams, personal attacks, politics, religion, etc.

REBOL 3.0
Updated 26-Apr-2024 - Edit - Copyright REBOL Technologies - REBOL.net