I've been getting my hands wet with emacs lisp, and one thing that trips me up sometimes is the dynamic scope. Is there much of a future for it? Most languages I know use static scoping (or have moved to static scoping, like Python), and probably because I know it better I tend to prefer it. Are there specific applications/instances or examples where dynamic scope is more useful?
There's a good discussion of this issue here. The most useful part that pertains to your question is:
Dynamic bindings are great for modifying the behaviour of subsystems. Suppose you are using a function ‘foo’ that generates output using ‘print’. But sometimes you would like to capture the output in a buffer of your choosing. With dynamic binding, it’s easy:
(let ((b (generate-new-buffer-name " *string-output*"))))
(let ((standard-output b))
(foo))
(set-buffer b)
;; do stuff with the output of foo
(kill-buffer b))
(And if you used this kind of thing a lot, you’d encapsulate it in a macro – but luckily it’s already been done as ‘with-output-to-temp-buffer’.)
This works because ‘foo’ uses the dynamic binding of the name ‘standard-output’, so you can substitute your own binding for that name to modify the behaviour of ‘foo’ – and of all the functions that ‘foo’ calls.
In a language without dynamic binding, you’d probably add an optional argument to ‘foo’ to specify a buffer and then ‘foo’ would pass that to any calls to ‘print’. But if ‘foo’ calls other functions which themselves call ‘print’ you’ll have to alter those functions as well. And if ‘print’ had another option, say ‘print-level’, you’d have to add that as an optional argument as well… Alternatively, you could remember the old value of ‘standard-output’, substitute your new value, call ‘foo’ and then restore the old value. And remember to handle non-local exits using ‘throw’. When you’re through with this, you’ll see that you’ve implemented dynamic binding!
That said, lexical binding is IMHO much better for 99% of the cases. Note that modern Lisps are not dynamic-binding-only like Emacs lisp.
In addition, modern languages like Python and Ruby that were somewhat inspired by Lisp usually support lexical-binding in a straightforward way, with dynamic binding also available but less straightforward.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With