Nested contexts in newLISP

newLisp does not have nested contexts. This is because contexts are not OO-style objects, although they can be used to prototype other contexts. In fact, contexts are name spaces that can be manually created as needed. However, since they create efficient hashes that can be used for many of the same purposes as objects (such as data modeling), it would be handy if there were a way to create contexts inside of other contexts.

Since we can store a symbol in a context, we can simply point a symbol to one context, then assign that symbol to another context, thus simulating a nested context.

(context 'profile "full-name" "Some Body")
(context 'profile "email" "")
(context 'account "username" "somebody")
(context 'account "password" "secret")
(context 'account "profile" 'profile)

However, accessing data from nested contexts begins to get hairy after a couple of levels:

(context (context 'account "profile") "email") ; => ""

To get around this, we write a function that automates this process. Since we would like to accept any number of levels in one expression, we’ll make it recursive:

(define (@ tree)
  (cond
    ((null? tree) nil)
    ((>= (length tree) 2)
      (if (> (length tree) 2)
          (@ (cons (context (tree 0) (name (tree 1))) (2 tree)))
          (context (tree 0) (name (tree 1)))))))

We use the symbol @ for no reason other than convenience. It will mean shorter expressions. We accept a quoted list of symbols as our one parameter. If it’s empty, we evaluate to nil. Otherwise, we recurse through the items in the list, getting the symbol’s value out of each level of context until we reach the end. Now, compare this syntax to that above:

(@ '(account profile email))
Leave a comment | Trackback
Jun 21st, 2007 | Posted in Programming
Tags:
No comments yet.