On Nov 11, 12:24 am, Paul Barry <[EMAIL PROTECTED]> wrote:
> In Common Lisp and Scheme, if you have an expression that evaluates a
> symbol, it doesn't evaluate it until you call the function, not when
> you define it. So you can do this:
>
> Common Lisp:
> [1]> (defun b () a)
> B
> [2]> (defvar a 5)
> A
> [3]> (b)
> 5
>
> Scheme:
> 1 ]=> (define (b) a)
> ;Value: b
> 1 ]=> (define a 5)
> ;Value: a
> 1 ]=> (b)
> ;Value: 5
>
> But you can't do this in Clojure:
> user=> (defn b [] a)
> java.lang.Exception: Unable to resolve symbol: a in this context
> (NO_SOURCE_FILE:1)
>
> But if you def a to something, you can then redef it and it will use
> the value defined later:
> user=> (def a nil)
> #=(var user/a)
> user=> (defn b [] a)
> #=(var user/b)
> user=> (def a 5)
> #=(var user/a)
> user=> (b)
> 5
>
> So is there a reason that Clojure tries to resolve symbols when you
> define a function? The downside of this is that when you have a file
> with multiple functions in it that call each other, you have to make
> sure they are defined in order of dependency.
I can't speak for Scheme, but CL resolves symbols earlier than does
Clojure - at read time. This causes a number of problems and a lot of
complexity [1].
In Clojure, I had to solve the Lisp-1 vs defmacro problem, and did so
by separating symbols from vars. That means that symbols are simple
when read, and only get resolved when compiled. Were compilation to
auto-create vars for never before seen symbols, many of the problems
of packages would remain, so I decided that vars and other name
resolutions needed to be created intentionally, via def/import/refer.
This leads to many fewer errors, and avoids the problems identified in
[1]. There is now a declare macro that makes it simple and obvious to
intentionally claim names for later use:
(declare a b c)
; ...def a b c in any order
This expands into (def a) (def b) (def c). Note that no initial values
are supplied, so they are unbound, and you will get a runtime error if
you use them before subsequently defining them, unlike your (def a
nil) above, which I don't recommend.
So, you don't need to define things in any specific order - use
declare.
Rich
[1] http://www.flownet.com/gat/packages.pdf
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---