Rich, Would you recommend using declare even if you are able to arrange your code to avoid dependency issues, or only if you can't work around it?
On Tue, Nov 11, 2008 at 9:16 AM, Rich Hickey <[EMAIL PROTECTED]> wrote: > > > > 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 -~----------~----~----~----~------~----~------~--~---