The Magic of Dynamic Scope

Posted on Mon, 1 Aug 2005 in Technology
Last edited Mon, 1 Aug 2005

Most programmers have been taught from time that they are very small children that global variables are evil. "Proper" programming wisdom teaches us to never ever use a global, no matter how convenient it may be. Now too be fair most of the people dispensing this advice are coming from a very odd point of view: they think you are going to write your application in C or Java. It may seem very odd that anyone would choose to write a program in such a language if they don't absolutely have too, but unfortunately it remains standard practice to use these languages for just about everything, and if you look at globals from a C programmers point of view, they are a total disaster. In C, globals kill reentrancy. In C globals are truly and irrevocably global, which means two instances of your program in the same address space have to share that variable, which usually means they simply cannot coexist. Global-ridden libraries cannot be used by more than one thread. They cannot be used in signal handlers, and it is very inconvenient (and probably impossible without the source) to use multiple instances of them even in a totally synchronous program. So where the heck do you put all of that global context that your program needs? Where do you put your output stream, and you xlib handle? Where do you put the --debug flag? A C programmer's answer to these questions is typical of the drudgery the poor wretch is always being forced to endure. He would say "You take all the things you want to be globals and stuff them in a structure called 'context' or something, and then pass the tiresome thing around between every function in your program".

Perhaps you don't mind passing context handles around like you have nothing better to do. Perhaps you don't mind casting every little object you pull out of a java.lang.Vector either. Maybe you don't even mind boxing your own ints so javac lets you pass them by reference. If you are such a person then by all means stick to C or Java or Fortran or an abacus or whatever you use. But if you are the sort of person that objects to doing the compilers job for it, then I am here to tell you that Yes, there is a better way. The answer to this problem of where to store all your global data if you can't use global variables is called dynamic scope. The idea is you simply put that data in global variables to start with, but allow those bindings to be locally shadowed by new ones. For example:

;; define a global variable *x* with initial value 'foo
(defvar *x* 'foo) 

;; define a function that prints *x*
(defun printx () 
  (print *x*)) 

;; this will print "foo"
(printx)

;; this will print "bar" and "baz"
(let ((*x* 'bar))     ;; create a new binding of the symbol *x* that is
                      ;; visible within this let form
  (printx) 
  (setq *x* 'baz)     ;; set *x* to 'baz
  (printx))

;; this will print "foo" again
(printx)

It might look like let is simply saving and restoring the value of *x* but in reality that is not what it's doing at all. Let is creating a whole new variable called *x*. Any code within the let, or any code called by any code within the let will have access to this new *x* instead of the global one. The distinction between creating a new variable and saving/restoring an existing one is that the new variable is unaffected by other threads, and the old variable cannot be fouled up by non-local exits (i.e. exceptions). The language guarantees that the only code that will see the new *x* is code that is truly inside the dynamic scope of the let. Dynamic scope is even perfectly compatible with continuations. It can be implemented in scheme via dynamic-wind

Dynamic scope is good for more than just storing output streams and debug flags. Together with non local exits, dynamic scope is the basis of common lisp's mind-blowingly awesome condition system. A condition is like an exception, except:

  • They need not be exceptional, i.e. the default response to someone throwing a condition is allowed to be "do nothing"
  • Code that signals conditions can provide restarts as well. A restart is a subroutine that can be called to recover from the condition and continue with the computation. For instance a lisp IMAP library might throw "invalid password" condition, but instead of simply quitting, it can provide restarts such as "try again" or "try a new password" or "try a different authentication method".
Lisp libraries can use conditions to provide a mechanism for error recovery, but leave the policy up to the code that calls them, and even provide a useful default. I'd like to see Java do that.

Security Solutions

Posted on Thu, 4 Aug 2005 in Technology
Last edited Thu, 4 Aug 2005

I heard an ad on the radio today for a "complete, centralized security solution". There is absolutely no such thing. Anyone trying to peddle you such a thing is a fraud. Security is not something that can be bolted on to an existing system. Securing an insecure computer system requires, at least, a careful code audit and a re-consideration of the system's architecture. Often it's easier to re-write the whole thing.

The best you can hope to bolt onto an insecure system is access control around the entire thing. That's better than nothing, and in some situations it may be adequate, but there's no substitute for proper design. Is your application privilege-separated? Are the privileged parts small? Are the parts that read untrusted input written defensively? These are the sort of questions that matter, and no shrink-wrapped "solution" will effect the answers.

Maddox rss

Posted on Mon, 15 Aug 2005 in Random
Last edited Mon, 22 Aug 2005

I made a lame rss feed of the best page in the universe. All it has is a link and one entry who's title and description are the hash of Maddox's page up too the counter at the end, but it should at least show up as a new entry in a rss reader when he posts something new. It's updated once a day.

Keyboard Macros and Structured Editing

Posted on Mon, 22 Aug 2005 in Technology
Last edited Wed, 31 May 2006
The combination of keyboard macros and structured editing commands can be super useful sometimes. I defined a bunch of macros called xdeffoo that would define and export something. I wrote a bunch of code that used them, but now I've decided this isn't very good style, and so I need to put them all back to normal deffoo's and put the symbols in my defpackge form to be exported. With any editor other than emacs this would be a pain in the but. I guess I could write a perl script to do it, but it wouldn't be as quick as what I actually did, which is this: set a keyboard macro that searches forward for xdef, deletes the x, skips to the next sexp (which is going to be the name of whatever is being defined), copies it, jumps back to where I was before the search, and pastes the name and a space. I hit the macro a bunch of times and, w00t, it's done, emacs p0wns you.
(let ((x (quote (quasiquote (let ((x (quote (unquote x)))) (unquote x))))))
  (quasiquote (let ((x (quote (unquote x)))) (unquote x))))