DictLib — Dictionary Library
Key/value storage for Plan9Basic programs. Dictionaries (associative arrays / maps) store and retrieve values using string keys instead of numeric indices. Three dictionary types are supported: numeric, string, and pointer.
| Category | Count | Description |
|---|---|---|
| Creation | 3 | dict#, sdict#, pdict# |
| Numeric Ops | 3 | dict_set#, dict_get, dict_getdef |
| String Ops | 3 | sdict_set#, sdict_get$, sdict_getdef$ |
| Pointer Ops | 3 | pdict_set#, pdict_get#, pdict_getdef# |
| Generic Ops | 8 | dict_exists, dict_haskey, dict_count, dict_remove, dict_clear#, dict_type, dict_typename$, dict_key$ |
| Type | Create With | Set | Get | Get w/ Default |
|---|---|---|---|---|
| Numeric | dict#() | dict_set#(d#, k$, n) | dict_get(d#, k$) | dict_getdef(d#, k$, def) |
| String | sdict#() | sdict_set#(d#, k$, s$) | sdict_get$(d#, k$) | sdict_getdef$(d#, k$, def$) |
| Pointer | pdict#() | pdict_set#(d#, k$, p#) | pdict_get#(d#, k$) | pdict_getdef#(d#, k$, def#) |
ⓘ Note: All dictionaries use string keys. Values are typed per dictionary. Dictionaries are garbage-collected automatically.
Dictionary Creation
| Function | Signature | Description |
|---|---|---|
dict#() | dict#@ | Create empty numeric dictionary |
sdict#() | sdict#@ | Create empty string dictionary |
pdict#() | pdict#@ | Create empty pointer dictionary |
' Numeric dictionary for ages ages# = dict#() dict_set#(ages#, "John", 25) dict_set#(ages#, "Mary", 30) println "John's age: "; dict_get(ages#, "John") ' String dictionary for capitals capitals# = sdict#() sdict_set#(capitals#, "France", "Paris") sdict_set#(capitals#, "Germany", "Berlin") println "Capital of France: "; sdict_get$(capitals#, "France") ' Pointer dictionary for objects objects# = pdict#() arr1# = dim#(10) pdict_set#(objects#, "first", arr1#)
Numeric Dictionary Operations
| Function | Signature | Description |
|---|---|---|
dict_set#(d#, key$, value) | dict_set#@#$n | Set numeric value (creates or updates key) |
dict_get(d#, key$) | dict_get@#$ | Get numeric value (error if key missing) |
dict_getdef(d#, key$, default) | dict_getdef@#$n | Get numeric value or default if key missing |
scores# = dict#() dict_set#(scores#, "Player1", 100) dict_set#(scores#, "Player2", 250) dict_set#(scores#, "Player1", 150) ' Updates Player1 println dict_get(scores#, "Player1") ' 150 println dict_getdef(scores#, "Player3", 0) ' 0 (default)
⚠ Warning:
dict_get() raises an error if the key doesn’t exist. Use dict_getdef() or check with dict_exists() first.String Dictionary Operations
| Function | Signature | Description |
|---|---|---|
sdict_set#(d#, key$, value$) | sdict_set#@#$$ | Set string value (creates or updates key) |
sdict_get$(d#, key$) | sdict_get$@#$ | Get string value (error if key missing) |
sdict_getdef$(d#, key$, default$) | sdict_getdef$@#$$ | Get string value or default if key missing |
config# = sdict#() sdict_set#(config#, "username", "admin") sdict_set#(config#, "server", "localhost") println sdict_get$(config#, "username") ' admin println sdict_getdef$(config#, "password", "none") ' none (default)
Pointer Dictionary Operations
| Function | Signature | Description |
|---|---|---|
pdict_set#(d#, key$, value#) | pdict_set#@#$# | Set pointer value (creates or updates key) |
pdict_get#(d#, key$) | pdict_get#@#$ | Get pointer value (error if key missing) |
pdict_getdef#(d#, key$, default#) | pdict_getdef#@#$# | Get pointer value or default if key missing |
arrays# = pdict#() data1# = dim#(100) data2# = sdim#(50) pdict_set#(arrays#, "numbers", data1#) pdict_set#(arrays#, "names", data2#) retrieved# = pdict_get#(arrays#, "numbers")
ⓘ Note: Pointer dictionaries are useful for storing collections of arrays, other dictionaries, or GUI control references by name.
Generic Dictionary Operations
These functions work with any dictionary type (numeric, string, or pointer).
| Function | Signature | Description |
|---|---|---|
dict_exists(d#, key$) | dict_exists@#$ | Check if key exists (returns 1 or 0) |
dict_haskey(d#, key$) | dict_haskey@#$ | Alias for dict_exists |
dict_count(d#) | dict_count@# | Number of key/value pairs |
dict_remove(d#, key$) | dict_remove@#$ | Remove key (returns 1 if removed, 0 if not found) |
dict_clear#(d#) | dict_clear#@# | Remove all entries (returns dict pointer) |
dict_type(d#) | dict_type@# | Type code: 0=numeric, 1=string, 2=pointer |
dict_typename$(d#) | dict_typename$@# | Type name: "numeric", "string", "pointer" |
dict_key$(d#, index) | dict_key$@#n | Key at 0-based index |
ages# = dict#() dict_set#(ages#, "John", 25) dict_set#(ages#, "Mary", 30) dict_set#(ages#, "Bob", 22) ' Check existence if dict_exists(ages#, "John") = 1 then println "John found: "; dict_get(ages#, "John") endif ' Count entries println "Entries: "; dict_count(ages#) ' 3 ' Iterate all keys (0-based index!) for i = 0 to dict_count(ages#) - 1 key$ = dict_key$(ages#, i) println key$; ": "; dict_get(ages#, key$) next ' Remove and clear dict_remove(ages#, "Bob") println "After remove: "; dict_count(ages#) ' 2 dict_clear#(ages#) println "After clear: "; dict_count(ages#) ' 0 ' Type info println dict_typename$(ages#) ' numeric
⚠ Warning:
dict_key$() uses 0-based indexing. Iterate from 0 to dict_count(d#) - 1. Key order is not guaranteed.Error Handling
| Error | Description |
|---|---|
| Null dictionary pointer | The dictionary pointer is null |
| Invalid dictionary object | The pointer doesn’t point to a valid dictionary |
| Type mismatch | Wrong dictionary type for the operation (e.g. using dict_get on a string dict) |
| Key not found | Attempted to get a non-existent key without using a default variant |
| Index out of bounds | Invalid index in dict_key$ |
ages# = dict#() ' Safe pattern: always check before get if dict_exists(ages#, "John") = 1 then println dict_get(ages#, "John") else println "Key not found" endif ' Or use getdef for a default value println dict_getdef(ages#, "John", 0) ' 0 (no error)
Complete Examples
Phone Book
' Phone book using string dictionary phonebook# = sdict#() sdict_set#(phonebook#, "John Smith", "555-1234") sdict_set#(phonebook#, "Mary Johnson", "555-5678") sdict_set#(phonebook#, "Bob Wilson", "555-9999") ' Look up a number name$ = "John Smith" if dict_exists(phonebook#, name$) = 1 then println name$; ": "; sdict_get$(phonebook#, name$) else println name$; " not found" endif ' List all contacts println "" println "All contacts:" for i = 0 to dict_count(phonebook#) - 1 name$ = dict_key$(phonebook#, i) println name$; " -> "; sdict_get$(phonebook#, name$) next
Word Counter
' Count word occurrences wordCount# = dict#() data "apple", "banana", "apple", "cherry", "banana", "apple" for i = 1 to 6 read word$ current = dict_getdef(wordCount#, word$, 0) dict_set#(wordCount#, word$, current + 1) next println "Word frequencies:" for i = 0 to dict_count(wordCount#) - 1 word$ = dict_key$(wordCount#, i) println word$; ": "; dict_get(wordCount#, word$) next
Configuration Manager
' App config using string dictionary config# = sdict#() sdict_set#(config#, "app.name", "MyApp") sdict_set#(config#, "app.version", "1.0") sdict_set#(config#, "db.host", "localhost") sdict_set#(config#, "db.port", "3306") sdict_set#(config#, "debug.enabled", "false") appName$ = sdict_get$(config#, "app.name") timeout$ = sdict_getdef$(config#, "timeout", "30") println "Application: "; appName$ println "Timeout: "; timeout$
Object Registry
' Store objects in a pointer dictionary registry# = pdict#() users# = sdim#(100) scores# = dim#(100) settings# = sdict#() pdict_set#(registry#, "users", users#) pdict_set#(registry#, "scores", scores#) pdict_set#(registry#, "settings", settings#) ' Retrieve an object if dict_exists(registry#, "scores") = 1 then myScores# = pdict_get#(registry#, "scores") myScores#[1] = 9999 println "Top score: "; myScores#[1] endif
Quick Reference
| Function | Signature | Description |
|---|---|---|
dict#() / sdict#() / pdict#() | *@ | Create numeric / string / pointer dictionary |
dict_set#(d#, k$, v) | dict_set#@#$n | Set numeric value |
dict_get(d#, k$) | dict_get@#$ | Get numeric (error if missing) |
dict_getdef(d#, k$, def) | dict_getdef@#$n | Get numeric or default |
sdict_set#(d#, k$, v$) | sdict_set#@#$$ | Set string value |
sdict_get$(d#, k$) | sdict_get$@#$ | Get string (error if missing) |
sdict_getdef$(d#, k$, def$) | sdict_getdef$@#$$ | Get string or default |
pdict_set#(d#, k$, v#) | pdict_set#@#$# | Set pointer value |
pdict_get#(d#, k$) | pdict_get#@#$ | Get pointer (error if missing) |
pdict_getdef#(d#, k$, def#) | pdict_getdef#@#$# | Get pointer or default |
dict_exists(d#, k$) | dict_exists@#$ | Key exists? (1/0) |
dict_haskey(d#, k$) | dict_haskey@#$ | Alias for dict_exists |
dict_count(d#) | dict_count@# | Number of entries |
dict_remove(d#, k$) | dict_remove@#$ | Remove key (1=removed, 0=not found) |
dict_clear#(d#) | dict_clear#@# | Remove all entries |
dict_type(d#) | dict_type@# | Type code: 0/1/2 |
dict_typename$(d#) | dict_typename$@# | Type name string |
dict_key$(d#, idx) | dict_key$@#n | Key at 0-based index |
20 functions: 3 creation + 9 typed get/set + 8 generic operations.