Re: Clojure compiletime vs runtime
Compilation is mandatory before executing anything. By default when code is loaded it's executed. That's how a Lisp behaves. If you want to isolate compilation, from execution, you can use AOT (ahead of time compilation). You would use this to deliver compiled code w/o source code, make sure there's no missing references, ... But this is not used in interactive development where you want to redefine stuff, change states, and be as dynamic as possible. Do you have a specific need that you want to cover ? Luc P. > Why are the toplevel forms which arent macros executed at compile time? For > example Lua can be compiled to bytecode without executing > its top level calls. > > > On Tue, Apr 15, 2014 at 9:04 PM, Softaddicts > wrote: > > > 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 clojure@googlegroups.com > > > Note that posts from new members are moderated - please be patient with > > your first post. > > > To unsubscribe from this group, send email to > > > clojure+unsubscr...@googlegroups.com > > > 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 clojure+unsubscr...@googlegroups.com. > > > For more options, visit https://groups.google.com/d/optout. > > > > > -- > > Softaddicts 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 clojure@googlegroups.com > > Note that posts from new members are moderated - please be patient with > > your first post. > > To unsubscribe from this group, send email to > > clojure+unsubscr...@googlegroups.com > > For more options, visit this
Re: Clojure compiletime vs runtime
I only noticed it because I was trying to write a macro which expands to multiple def calls. This requires the def's to be inside a do block, which made me question a whole lot about how the AOT compiler works. On Tue, Apr 15, 2014 at 11:05 PM, Phillip Lord wrote: > > You need to distinguish between "compiled" and "aot compiled to byte > code". > > As far as I know, all forms are compiled before they are executed. So, > if you type: > > (+ 1 1) > > it is first compiled to bytecode, and then run. It's not executed at > compile time at all; rather when it is evaluated, it is compiled and > then run. If you aot compile, then you are do the same thing, but dump > the bytecode to file. So, you still evaluate the entire top level. > > So, when you say compile, I presume you you mean aot compiled. Macros > have to be run, so the question is should they be expanded but not > evaluated? And what about macros with side-effects? > > And if top level forms are NOT evaluated when loaded what would this do: > > (ns user) > (def x 1) > > (load "user_y") > > === in user_y.clj > (def y 1) > > > Now the AOT would only load the first file in the namespace because > (load "user_y") would not be evaluated. > > Why are you worried about this? Most of the time compilation in Clojure > is an implementation detail, as it is in python. It just happens when it > needs to, and away you go. > > Phil > > > > Andrew Chambers writes: > > Why are the toplevel forms which arent macros executed at compile time? > For > > example Lua can be compiled to bytecode without executing > > its top level calls. > > > > > > On Tue, Apr 15, 2014 at 9:04 PM, Softaddicts < > lprefonta...@softaddicts.ca>wrote: > > > >> 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 clojure@googlegroups.c
Re: Clojure compiletime vs runtime
You need to distinguish between "compiled" and "aot compiled to byte code". As far as I know, all forms are compiled before they are executed. So, if you type: (+ 1 1) it is first compiled to bytecode, and then run. It's not executed at compile time at all; rather when it is evaluated, it is compiled and then run. If you aot compile, then you are do the same thing, but dump the bytecode to file. So, you still evaluate the entire top level. So, when you say compile, I presume you you mean aot compiled. Macros have to be run, so the question is should they be expanded but not evaluated? And what about macros with side-effects? And if top level forms are NOT evaluated when loaded what would this do: (ns user) (def x 1) (load "user_y") === in user_y.clj (def y 1) Now the AOT would only load the first file in the namespace because (load "user_y") would not be evaluated. Why are you worried about this? Most of the time compilation in Clojure is an implementation detail, as it is in python. It just happens when it needs to, and away you go. Phil Andrew Chambers writes: > Why are the toplevel forms which arent macros executed at compile time? For > example Lua can be compiled to bytecode without executing > its top level calls. > > > On Tue, Apr 15, 2014 at 9:04 PM, Softaddicts > wrote: > >> 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 clojure@googlegroups.com >> > Note that posts from new members are moderated - please be patient with >> your first post. >> > To unsubscribe from this group, send email to >> > clojure+unsubscr...@googlegroups.com >> > 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 clojure+unsubscr...@googlegroups.com. >> > For more options, visit https://groups.goog
Re: Clojure compiletime vs runtime
Why are the toplevel forms which arent macros executed at compile time? For example Lua can be compiled to bytecode without executing its top level calls. On Tue, Apr 15, 2014 at 9:04 PM, Softaddicts wrote: > 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 clojure@googlegroups.com > > Note that posts from new members are moderated - please be patient with > your first post. > > To unsubscribe from this group, send email to > > clojure+unsubscr...@googlegroups.com > > 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 clojure+unsubscr...@googlegroups.com. > > For more options, visit https://groups.google.com/d/optout. > > > -- > Softaddicts 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 clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to a topic in the > Google Groups "Clojure" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/clojure/VUWTAwOEHS0/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.
Re: Clojure compiletime vs runtime
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 clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > 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 clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- Softaddicts 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 clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com 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 clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Clojure compiletime vs runtime
Forgive me, the first example was meant to be The following code wont compile: (defn y[]) ((x)) (defn x [] nil) On Tuesday, April 15, 2014 4:39:59 PM UTC+12, Andrew Chambers wrote: > > 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 clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com 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 clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.