Re: "Binding" and temporary global state
On 6 September 2010 23:22, Cameron Pulsford wrote: [...] > Changing my declares to defs did the trick did though and learning Does this break it again? (do (def *macros*)) Because that's all that declare does: user=> (macroexpand-1 '(declare *macros*)) (do (def *macros*)) -- Michael Wood -- 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
Re: "Binding" and temporary global state
I am a bit puzzled, I did a quick test and rebinding using a declare should work (outside of your sample code). I have a reminiscence of a similar problem I encountered before version 1.0 and used a def to solve my problem at the time. But the small test I just made with 1.2 is working. There's a context issue I do not quite grasp here... or I am aging fast... Luc. Cameron Pulsford wrote .. > Interesting results. > > By putting (println compiled-ops) it worked, but not by putting it in > a doall. (same error) > > Changing my declares to defs did the trick did though and learning > about bound-fn* was also a serious mind-expander for me right now too. > > Thanks to both of you! > > On Sep 6, 4:57 pm, Jarkko Oranen wrote: > > Cameron Pulsford wrote: > > > Is there a way to do this? Besides cleaning up function signatures is > > > this a premature optimization to begin with? > > > > > (declare *macros*) > > > > > (defn macro-expand [tokens] > > > (map #(get *macros* % %) tokens)) > > > > > (defn compile-op [op] > > > (macro-expand op)) > > > > > (defn assemble [{:keys [macros syms blks fncs]}] > > > (binding [*macros* macros] ;; I thought binding would handle this, > > > but I must be misusing it > > > (let [compiled-ops (map compile-op fncs)] > > > compiled-ops))) > > > > Your problem is that compiled-ops is a lazy sequence, and it only gets > > realised when it's used, which probably happens after it has exited > > the dynamic scope where *macros* is bound. > > > > You can work around the problem by forcing the sequence with doall or > > by using bound-fn* to save the dynamic environment (ie. (map (bound- > > fn* compile-op) fns), though double check that from the docs) > > -- > 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 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
Re: "Binding" and temporary global state
Interesting results. By putting (println compiled-ops) it worked, but not by putting it in a doall. (same error) Changing my declares to defs did the trick did though and learning about bound-fn* was also a serious mind-expander for me right now too. Thanks to both of you! On Sep 6, 4:57 pm, Jarkko Oranen wrote: > Cameron Pulsford wrote: > > Is there a way to do this? Besides cleaning up function signatures is > > this a premature optimization to begin with? > > > (declare *macros*) > > > (defn macro-expand [tokens] > > (map #(get *macros* % %) tokens)) > > > (defn compile-op [op] > > (macro-expand op)) > > > (defn assemble [{:keys [macros syms blks fncs]}] > > (binding [*macros* macros] ;; I thought binding would handle this, > > but I must be misusing it > > (let [compiled-ops (map compile-op fncs)] > > compiled-ops))) > > Your problem is that compiled-ops is a lazy sequence, and it only gets > realised when it's used, which probably happens after it has exited > the dynamic scope where *macros* is bound. > > You can work around the problem by forcing the sequence with doall or > by using bound-fn* to save the dynamic environment (ie. (map (bound- > fn* compile-op) fns), though double check that from the docs) -- 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
Re: "Binding" and temporary global state
Oups, forget about my last post, I was under the impression you could not bind to a declared thing... wrong was I... Luc P. lprefonta...@softaddicts.ca wrote .. > Hi Cameron, > > Use def or defvar (if you use contrib.def) to create an instance of *macros*. > Declare is used for forward references (when you reference something > before declaring it) so the compiler knows that your code is sane but it does > not "define" anything by itself. > > Yes, it may look a bit confusing at first glance but declaring > something and defining something are not the same...thing :))) > > Luc P, > > Cameron Pulsford wrote .. > > Hello all, here is an extremely reduced version of a problem I'm not > > sure how to work around. (It's going to be a toy assembly language if > > anyone's wondering) When I call assemble in the following code I get > > the error: "java.lang.IllegalStateException: Var reader/*macros* is > > unbound." I'd like *macros* to always be rebound for whatever source > > file is being compiled and I'd rather not explicitly pass the map of > > macros (and other things not shown here) to every function in the > > hierarchy just to supply some of the bottom level worker functions > > with the information they need. > > > > Is there a way to do this? Besides cleaning up function signatures is > > this a premature optimization to begin with? > > > > (declare *macros*) > > > > (defn macro-expand [tokens] > > (map #(get *macros* % %) tokens)) > > > > (defn compile-op [op] > > (macro-expand op)) > > > > (defn assemble [{:keys [macros syms blks fncs]}] > > (binding [*macros* macros] ;; I thought binding would handle this, > > but I must be misusing it > > (let [compiled-ops (map compile-op fncs)] > > compiled-ops))) > > > > > > > > -- > > 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 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 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
Re: "Binding" and temporary global state
Hi Cameron, Use def or defvar (if you use contrib.def) to create an instance of *macros*. Declare is used for forward references (when you reference something before declaring it) so the compiler knows that your code is sane but it does not "define" anything by itself. Yes, it may look a bit confusing at first glance but declaring something and defining something are not the same...thing :))) Luc P, Cameron Pulsford wrote .. > Hello all, here is an extremely reduced version of a problem I'm not > sure how to work around. (It's going to be a toy assembly language if > anyone's wondering) When I call assemble in the following code I get > the error: "java.lang.IllegalStateException: Var reader/*macros* is > unbound." I'd like *macros* to always be rebound for whatever source > file is being compiled and I'd rather not explicitly pass the map of > macros (and other things not shown here) to every function in the > hierarchy just to supply some of the bottom level worker functions > with the information they need. > > Is there a way to do this? Besides cleaning up function signatures is > this a premature optimization to begin with? > > (declare *macros*) > > (defn macro-expand [tokens] > (map #(get *macros* % %) tokens)) > > (defn compile-op [op] > (macro-expand op)) > > (defn assemble [{:keys [macros syms blks fncs]}] > (binding [*macros* macros] ;; I thought binding would handle this, > but I must be misusing it > (let [compiled-ops (map compile-op fncs)] > compiled-ops))) > > > > -- > 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 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
Re: "Binding" and temporary global state
Cameron Pulsford wrote: > Is there a way to do this? Besides cleaning up function signatures is > this a premature optimization to begin with? > > (declare *macros*) > > (defn macro-expand [tokens] > (map #(get *macros* % %) tokens)) > > (defn compile-op [op] > (macro-expand op)) > > (defn assemble [{:keys [macros syms blks fncs]}] > (binding [*macros* macros] ;; I thought binding would handle this, > but I must be misusing it > (let [compiled-ops (map compile-op fncs)] > compiled-ops))) Your problem is that compiled-ops is a lazy sequence, and it only gets realised when it's used, which probably happens after it has exited the dynamic scope where *macros* is bound. You can work around the problem by forcing the sequence with doall or by using bound-fn* to save the dynamic environment (ie. (map (bound- fn* compile-op) fns), though double check that from the docs) -- 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
"Binding" and temporary global state
Hello all, here is an extremely reduced version of a problem I'm not sure how to work around. (It's going to be a toy assembly language if anyone's wondering) When I call assemble in the following code I get the error: "java.lang.IllegalStateException: Var reader/*macros* is unbound." I'd like *macros* to always be rebound for whatever source file is being compiled and I'd rather not explicitly pass the map of macros (and other things not shown here) to every function in the hierarchy just to supply some of the bottom level worker functions with the information they need. Is there a way to do this? Besides cleaning up function signatures is this a premature optimization to begin with? (declare *macros*) (defn macro-expand [tokens] (map #(get *macros* % %) tokens)) (defn compile-op [op] (macro-expand op)) (defn assemble [{:keys [macros syms blks fncs]}] (binding [*macros* macros] ;; I thought binding would handle this, but I must be misusing it (let [compiled-ops (map compile-op fncs)] compiled-ops))) -- 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