Call-tables

A more convenient way to use hash tables.

A call-table is a lexically closed function wrapping a hash table.

Calling it with two arguments sets a key to that value.

Calling it with one argument retrieves the value for that key.

⇒ (strawberry lemon lemon-balm)

You can change your mind and update existing keys:

⇒ parsley

Initial values

The initial value for unknown keys is #f.

⇒ #f

You can set another initial value when creating the call-value.

⇒ 5

Popping that hood

Abstraction is great when it helps us. We don’t want to put too many hoops in our own way.

You can access the underlying hash table by calling the call-table without any arguments.

⇒ #t

You can swap out the underlying hash table by using the keyword update: and a hash table. This is currently the only key with a special meaning.

⇒ (red yellow green)

It specifically only listens for the combination of the keyword update: and the value type hash-table. Other key/value pairs aren’t treated specially.

⇒ “a string”

call-table* — value collectors

The vanilla call-table replaces its values. Sometimes, you instead want to keep accumulating new values.

⇒ ((blueberry) (raspberry strawberry))

Custom accumulating

The default is to cons the new values onto a list of the old ones.

You can change that:

⇒ (0 0 4 2 0)

You can also hack this to get a call-table that loves to add new stuff but refuses to overwrite what’s already there:

⇒ 13

⇒ 14

⇒ 13

Unary accumulating

Sometimes, it’s even useful to just have a unary procedure.

With unary procedures, while each call returns the new value (which can often be useful enough), there’s no read-only idempotent way to just retrieve values unless you access the entire hash table.

⇒ ((garden . 2) (gazebo . 1))

But that’s where our under-the-hood access can come in handy:

There were 4 ghosts in the attic.

There were 1 ghosts in the gazebo.

There were 2 ghosts in the garden.

There were 2 ghosts in the basement.

set! support

You can also use set! to set slots.

On a call-table*, the new values are added to the accumulators, rather than replacing them.

⇒ (watermelon raspberry strawberry)

You can also swap out the underlying hash-table.

Starting with something

You can include an alist or a hash-table while first creating your call-table.

call-key*

Sometimes you think call-table is convenient but you only need one key.

For call-key, just use make-parameter.

But call-key* is awesome since it accumulates its values.

It has the same proc, unary, and initial keyword arguments as call-table*. It doesn’t have seed because the idea is that you just use initial. The generated procedure has update (which takes a new list as argument) and get (which you only need for unary call-keys).

⇒ (tornado kind-girl ruby)

Source code

call-table and call-table* are part of brev-separate.