Ahem :)
a) The fn x does not exist in the universe until you call foo, hence you cannot
expect the compiler to known anything about it if it's not called before
making any reference to x.
b) If you refer to x at the top level (the "universe" above :) before defining
it, obviously it does not exist. You might use (declare x) before
referring to it. This allows you to define it later at your convenience.
c) In general, you should avoid using def/defn within a function.
Macros may do that but this is a different story.
d) Yes code at the top level is executed, how can you expect
the REPL to work interactively if forms are not evaluated first ?
A defn expands to a function call, a special form in fact but it still
behaves
like a function. Any function call at top level will get executed after
being
compiled to byte code.
Now about the "compilation" step...
Traditionally, most Lisps allow you to refer to stuff in interpreted mode
not defined yet hoping that it will get defined by the time you run the code
that refers to these undefined things. It can even be something transient on
the stack... oups...
You can still compile in other Lisps but this is a special case where you have
to
make sure that stuff is defined in some way. You need to add directives to
tell the compiler that this stuff will exist later and that it can safely refer
to it.
On the JVM, some underlying byte code has to be generated for any forms
typed in the REPL at the top level any reference has to be defined before hand.
There's no other way to generate byte code... there cannot be black holes
waiting to get filled later.
Hence the "compilation" phase and the restriction
that stuff you refer to are to be defined either directly or using declare.
Hope it explains the compromise.
Luc P.
> Is there an explanation of how clojure deals with scoping and its static
> checking. It seems to be a hybrid of a static language and a dynamic
> language when it comes to compilation. I'll elaborate.
>
> The following code wont compile:
> (defn x [] nil)
> (defn y[]) ((x))
>
> however this code will compile:
>
> (defn foo[] (defn x[] nil))
> (defn y[]) ((x))
>
> but calling y before foo fails with a runtime exception.
>
> Also, the following code:
>
> (println "hello")
> (defn -main [args]
> (println "world"))
>
> prints "hello" at compile time
> and also
> "hello
> world" at runtime.
>
> My conclusions from this is that the static symbol checker is actually
> fairly stupid and is just there to provide some simple sanity, and that all
> toplevel code in a namespace
> is executed at compile time AND at runtime. Is this correct?
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to [email protected]
> Note that posts from new members are moderated - please be patient with your
> first post.
> 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
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>
--
Softaddicts<[email protected]> sent by ibisMail from my ipad!
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
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
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.