Fundamental data structures like lists and hashes have been needed in IDL for some time, but IDL 8.0 introduces them along with some related features/syntax for object-oriented programming to make them even more useful.

A list is simply a sequentially ordered container of items of any type. You can add/insert items, remove items, look up an item at a given index, etc. It is similar to an IDL_Container, except that it allows its items to be of any type, not just objects (and the items don’t have to even all be of the same type). For example,

IDL> stations = list()
IDL> stations->add, 'Boulder'
IDL> ; try the following without the EXTRACT keyword too
IDL> stations->add, ['Fort Collins', 'Denver'], /extract
IDL> stations->add, ['Colorado Springs']
IDL> print, n_elements(stations)
4
IDL> print, stations
Boulder
Fort Collins
Denver
Colorado Springs
IDL> print, stations[1]
Fort Collins
IDL> foreach s, stations do print, strupcase(s)
BOULDER
FORT COLLINS
DENVER
COLORADO SPRINGS

Hashes are another type of container, but ordered by arbitrary keys instead of by an integer index. For example,

IDL> zip_codes = hash()
IDL> zip_codes[80303] = 'Boulder'
IDL> zip_codes[80521] = 'Fort Collins'
IDL> zip_codes[80002] = 'Denver'
IDL> zip_codes[80840] = 'Colorado Springs'
IDL> print, zip_codes
80840: Colorado Springs
80521: Fort Collins
80002: Denver
80303: Boulder
IDL> print, zip_codes[80303]
Boulder
IDL> print, zip_codes->keys()
80840
80521
80002
80303
IDL> print, zip_codes->values()
Colorado Springs
Fort Collins
Denver
Boulder
IDL> foreach city, zip_codes, code do $
IDL>   print, code, city, format='(%"Zip code %d is in %s")'
Zip code 80840 is in Colorado Springs
Zip code 80521 is in Fort Collins
Zip code 80002 is in Denver
Zip code 80303 is in Boulder

For an example of more extensive use of lists and hashes, I implemented Peter Norvig’s spelling corrector in IDL (download):

IDL> print, mg_spellcorrect('corect')
correct
IDL> print, mg_spellcorrect('correct')
correct
IDL> print, mg_spellcorrect('speling')
spelling

Norvig’s Python implementation uses some list features that IDL does not have like list comprehensions, but IDL’s lists and hashes were up for the task (though it’s regular expressions were not and I had to make a few optimizations to get IDL’s implementation to a reasonable speed, so the first time you run mg_spellcorrect will take longer while it generates the word list and saves it away).

I have my own list and hash classes which provide similar functionality, but require elements of lists and keys/values of hashes to be of a single type. This provides a bit of extra performance (and in practice I never needed to have a single list or hash containing items of differing types) against earlier versions of the IDL list and hash objects, but lists and hashes are faster in the final IDL 8.0 release, as seen in this comparison between adding items to standard arrays, lists, and MGcoArrayLists:

Concatenation

UPDATE 2/23: Fixed x-axis scale on above graph. Code for running the test is available (though the graphics code requires a bunch of my private routines).