|One of Arc's neat features is the ability to use non-functions in functional position. This makes data access much more concise and simple.|
Unfortunately, it's not possible to manually define how to handle user-defined types in functional position. This means that user-defined types are less powerful than built-in types, which we all know is a bad thing.
Thus, I've just pushed a small change to ac.scm in the Git wiki. When it goes to figure out how to call a non-function object, it no longer uses a big old hard-coded cond. Instead, it checks a table, call, defined and populated in Arc code. This table associates types with functions to use to call those types.
I've also added a little macro called "defcall" that's provides a nice interface for defining one of the functions. The syntax is
As an example of how this works, I'll define a very simple 'alist type:
(defcall type (obj . args)
PG, I seem to remember you expressing interest in making this customizable - is this sort of what you had in mind?
arc> (defcall alist (al key)
(alref al key))
arc> (= al (annotate 'alist '(("foo" "A metasyntactic variable.")
("peanut butter" "A tasty spread."))))
#3(tagged alist (("foo" "A metasyntactic variable." . nil) ("peanut butter" "A tasty spread." . nil) . nil))
arc> (al "foo")
"A metasyntactic variable."