Re: More functional Quil
Hello Nikita, I think Quil should definitely provide a way to write functional style processing code. At the moment, my knowledge of both Clojure and Processing is not enough to evaluate these solutions. I'm certainly going to write my code following some of this and if someone proposes a solution to be part of Quil 2, I would happily adopt it and report back on my experiences. BTW, I noticed you had some discussions on IRC, you can find me there as Pupeno. On Monday, March 10, 2014 12:29:00 AM UTC, Nikita Beloglazov wrote: Hi Pablo You can find similar old thread on Quil github repo: https://github.com/quil/quil/pull/19 It may serve as good background what other people considered to make Quil more functional-style. I like your suggestion though I would split your :draw function to 2 fns: an :update function, which only purpose is to update state and :drawwhich draws state and doesn't change the world at all. If this approach is implemented - other handler functions like :mouse-move, :key-pressed are also need to become update-like functions - they should take state as argument and return new state. The only problem is that it is not backward compatible at all. But probably we still can do it... We can add option :fun-mode? true (stands for functional-mode) which enables all these changes - :draw takes state as argument, new :update function is added for modifying state, all handlers behave like :update. This option is enabled per-sketch. It requires additional work on Quil internals, but I think it is doable. This option can be implemented in coming quil 2.0 and it would be great feature to have. One more thing we could do to make it more functional-like - pass changed values to handlers directly. Currently when :key-pressedhandler is called - no argument is passed to the function and you need to use (key-code) or (raw-key) functions to identify which key was pressed. I think this parameters should be explicitly passed to the function. What do you think? Nikita On Sunday, March 9, 2014 1:21:58 PM UTC, J. Pablo Fernández wrote: On Sunday, March 9, 2014 1:02:52 PM UTC, Laurent PETIT wrote: Hello, To be honest I don't see any fundamental difference between your first attempt and the improvement: both share the fact that the mutation of the state happens within the draw function. So in both cases, you have a temporal coupling between updating the state of the app and rendering a new view of the app's state. Yes, what's happening in both cases is very similar, but the function draw in the functional style, in my opinion, is easier to read and maybe it's also easier to test. I would suggest that you don't swap! at all within draw, just deref and render the result of the dereffing. And, in another thread, at potentially a totally different pace than the redrawing's pace, update the application's state accordingly to business rules / constraints. Schematically, something like this: (def app-state (atom (init-state))) (defn draw [...] (let [app-snapshot (deref app-state)] ... call quil primitives to render the application state snapshot ...)) (future ... logic which updates the app-state atom depending on business rules / constraints, in a separate thread ...) I never worked with future, this is exciting, but I have some questions. Do you mean that future is completely separate from draw? I'm just getting started, but draw is not only a function to draw, but as a side effect is the clock of the app, as it's called according to the set frames per second and you normally *take a step* en each draw. Would draw create these futures for the next draw? -- 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: More functional Quil
Lee, I think question about managing/updating state in quil pop ups pretty frequently and many people expect quil to have built-in tools to do it in functional style. And using atoms to update state may feel hacky. I think this tools should exist and quil 2.0 is a good time to address the issue. Yes, Pablo's and mine changes are cosmetic but still they will help to feel functional nature of quil and I think it is a win. As for translating Processing code to Quil - I think it's already not very easy for people who has little experience with functional programming and therefore I don't think these cosmetic changes will add much complexity. The only issue I see, which is you mentioned, is having two similar but still separate modes. It may create confusion for newcomers. Though I will be glad to hear other opinions on the question and see if people generally like the idea or would rather keep old good quil as it is. Gary, Thank you. It might be useful in future if we decide to implement similar thing. Thank you, Nikita On Mon, Mar 10, 2014 at 4:27 AM, Gary Trakhman gary.trakh...@gmail.comwrote: FWIW, I've got an example of a decoupled update/draw loop here: https://github.com/gtrak/quilltest/blob/master/src/quilltest/balls.clj On Sun, Mar 9, 2014 at 10:16 PM, Lee Spector lspec...@hampshire.eduwrote: FWIW I'm not crazy about these suggestions because they seem to me to be mostly cosmetic, and actually negative if they end up leading to multiple incompatible modes of operation. The Processing model seems to me to be intrinsically imperative, and it's also well-known by lots of people and easy to understand. The current Quil scheme, which provides fairly direct access to Processing's existing model from Clojure, still allows us to write functional-style code for all of the interesting stuff that we do within/between calls to the imperative Processing calls. And it allows one to translate Processing ideas into Quil relatively easily. So I like it like it is :-). -Lee On Mar 9, 2014, at 8:29 PM, Nikita Beloglazov wrote: Hi Pablo You can find similar old thread on Quil github repo: https://github.com/quil/quil/pull/19 It may serve as good background what other people considered to make Quil more functional-style. I like your suggestion though I would split your :draw function to 2 fns: an :update function, which only purpose is to update state and :draw which draws state and doesn't change the world at all. If this approach is implemented - other handler functions like :mouse-move, :key-pressed are also need to become update-like functions - they should take state as argument and return new state. The only problem is that it is not backward compatible at all. But probably we still can do it... We can add option :fun-mode? true (stands for functional-mode) which enables all these changes - :draw takes state as argument, new :update function is added for modifying state, all handlers behave like :update. This option is enabled per-sketch. It requires additional work on Quil internals, but I think it is doable. This option can be implemented in coming quil 2.0 and it would be great feature to have. One more thing we could do to make it more functional-like - pass changed values to handlers directly. Currently when :key-pressed handler is called - no argument is passed to the function and you need to use (key-code) or (raw-key) functions to identify which key was pressed. I think this parameters should be explicitly passed to the function. What do you think? Nikita -- 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. -- 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/UQ3iPC6Oj9g/unsubscribe. To unsubscribe from this group and all its topics, send an email to
Re: More functional Quil
The complicated-looking semaphore code was adapted from http://stackoverflow.com/a/5275254/2559313 . I think some issues with other alternatives are in there. On Mon, Mar 10, 2014 at 1:27 PM, Nikita Beloglazov nikelandj...@gmail.comwrote: Lee, I think question about managing/updating state in quil pop ups pretty frequently and many people expect quil to have built-in tools to do it in functional style. And using atoms to update state may feel hacky. I think this tools should exist and quil 2.0 is a good time to address the issue. Yes, Pablo's and mine changes are cosmetic but still they will help to feel functional nature of quil and I think it is a win. As for translating Processing code to Quil - I think it's already not very easy for people who has little experience with functional programming and therefore I don't think these cosmetic changes will add much complexity. The only issue I see, which is you mentioned, is having two similar but still separate modes. It may create confusion for newcomers. Though I will be glad to hear other opinions on the question and see if people generally like the idea or would rather keep old good quil as it is. Gary, Thank you. It might be useful in future if we decide to implement similar thing. Thank you, Nikita On Mon, Mar 10, 2014 at 4:27 AM, Gary Trakhman gary.trakh...@gmail.comwrote: FWIW, I've got an example of a decoupled update/draw loop here: https://github.com/gtrak/quilltest/blob/master/src/quilltest/balls.clj On Sun, Mar 9, 2014 at 10:16 PM, Lee Spector lspec...@hampshire.eduwrote: FWIW I'm not crazy about these suggestions because they seem to me to be mostly cosmetic, and actually negative if they end up leading to multiple incompatible modes of operation. The Processing model seems to me to be intrinsically imperative, and it's also well-known by lots of people and easy to understand. The current Quil scheme, which provides fairly direct access to Processing's existing model from Clojure, still allows us to write functional-style code for all of the interesting stuff that we do within/between calls to the imperative Processing calls. And it allows one to translate Processing ideas into Quil relatively easily. So I like it like it is :-). -Lee On Mar 9, 2014, at 8:29 PM, Nikita Beloglazov wrote: Hi Pablo You can find similar old thread on Quil github repo: https://github.com/quil/quil/pull/19 It may serve as good background what other people considered to make Quil more functional-style. I like your suggestion though I would split your :draw function to 2 fns: an :update function, which only purpose is to update state and :draw which draws state and doesn't change the world at all. If this approach is implemented - other handler functions like :mouse-move, :key-pressed are also need to become update-like functions - they should take state as argument and return new state. The only problem is that it is not backward compatible at all. But probably we still can do it... We can add option :fun-mode? true (stands for functional-mode) which enables all these changes - :draw takes state as argument, new :update function is added for modifying state, all handlers behave like :update. This option is enabled per-sketch. It requires additional work on Quil internals, but I think it is doable. This option can be implemented in coming quil 2.0 and it would be great feature to have. One more thing we could do to make it more functional-like - pass changed values to handlers directly. Currently when :key-pressed handler is called - no argument is passed to the function and you need to use (key-code) or (raw-key) functions to identify which key was pressed. I think this parameters should be explicitly passed to the function. What do you think? Nikita -- 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. -- 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
More functional Quil
Hello Clojurians, I'm starting to play with Processing and I want to use my favorite programming language for it, so I started using Quilhttps://github.com/quil/quil. The problem is that Processing has a imperative architecture and makes my Clojure code look bad. For those that don't know Processing/Quil, here's a little overview that's relevant to this email. Processing is a language and a library that makes it easy to draw on the screen to do generative art, simulations, etc. Processing programs have two methods, a setup method that is run once, at the beginning, and then a draw method that is run over and over. Literally something like: Walker w; void setup() { w = new Walker(); } void draw() { w.render(); w.walk(); } I'm using a hypothetical walker, an entity that walks around the screen. More or less taken from here: http://natureofcode.com/book/introduction/ My understanding is that the equivalent Clojure code using Quil would look like this: (defn setup [] (set-state! :walker (atom (create-walker (defn draw [] (render-walker @(state :walker)) (swap! (state :walker) walk)) Quil stores a map in the meta-data of the Processing applet and let's you access it. Since I need the state to change, I'm storing the walker in an atom. I found examples out there following more or less this structure. I'm not happy with this structure, it doesn't feel functional enough. When thinking about this, I got reminded of Erlang processes, specially with OTP, where you have a function that's called over and over to which the state is passed and which returns the next state. Following that structure I would like to implement it like this: (defn setup [] [(create-walker)]) (defn draw [walker] (render-walker walker) [(walk walker)]) The result of calling setup is a vector containing the attributes to draw, and the result of draw is a vector containing the attributes that will be used in the next call to draw. Does this make sense? Does it look cleaner to you guys? I achieved that by writing this wrappers for setup and draw: (defn setup-wrapper [] (set-state! :state (atom (setup (defn draw-wrapper [] (swap! (state :state) (fn [s] (apply draw s My concern with this is that now the whole state is in one single atom that I'm replacing on each frame and that might not be good. Is it copying the whole state or can Clojure use its copy-on-demand feature even for atoms? Is there a better way of doing this? Thanks. -- 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: More functional Quil
Hello, To be honest I don't see any fundamental difference between your first attempt and the improvement: both share the fact that the mutation of the state happens within the draw function. So in both cases, you have a temporal coupling between updating the state of the app and rendering a new view of the app's state. I would suggest that you don't swap! at all within draw, just deref and render the result of the dereffing. And, in another thread, at potentially a totally different pace than the redrawing's pace, update the application's state accordingly to business rules / constraints. Schematically, something like this: (def app-state (atom (init-state))) (defn draw [...] (let [app-snapshot (deref app-state)] ... call quil primitives to render the application state snapshot ...)) (future ... logic which updates the app-state atom depending on business rules / constraints, in a separate thread ...) HTH, -- Laurent 2014-03-09 13:47 GMT+01:00 J. Pablo Fernández pup...@pupeno.com: Hello Clojurians, I'm starting to play with Processing and I want to use my favorite programming language for it, so I started using Quilhttps://github.com/quil/quil. The problem is that Processing has a imperative architecture and makes my Clojure code look bad. For those that don't know Processing/Quil, here's a little overview that's relevant to this email. Processing is a language and a library that makes it easy to draw on the screen to do generative art, simulations, etc. Processing programs have two methods, a setup method that is run once, at the beginning, and then a draw method that is run over and over. Literally something like: Walker w; void setup() { w = new Walker(); } void draw() { w.render(); w.walk(); } I'm using a hypothetical walker, an entity that walks around the screen. More or less taken from here: http://natureofcode.com/book/introduction/ My understanding is that the equivalent Clojure code using Quil would look like this: (defn setup [] (set-state! :walker (atom (create-walker (defn draw [] (render-walker @(state :walker)) (swap! (state :walker) walk)) Quil stores a map in the meta-data of the Processing applet and let's you access it. Since I need the state to change, I'm storing the walker in an atom. I found examples out there following more or less this structure. I'm not happy with this structure, it doesn't feel functional enough. When thinking about this, I got reminded of Erlang processes, specially with OTP, where you have a function that's called over and over to which the state is passed and which returns the next state. Following that structure I would like to implement it like this: (defn setup [] [(create-walker)]) (defn draw [walker] (render-walker walker) [(walk walker)]) The result of calling setup is a vector containing the attributes to draw, and the result of draw is a vector containing the attributes that will be used in the next call to draw. Does this make sense? Does it look cleaner to you guys? I achieved that by writing this wrappers for setup and draw: (defn setup-wrapper [] (set-state! :state (atom (setup (defn draw-wrapper [] (swap! (state :state) (fn [s] (apply draw s My concern with this is that now the whole state is in one single atom that I'm replacing on each frame and that might not be good. Is it copying the whole state or can Clojure use its copy-on-demand feature even for atoms? Is there a better way of doing this? Thanks. -- 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. -- 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: More functional Quil
On Sunday, March 9, 2014 1:02:52 PM UTC, Laurent PETIT wrote: Hello, To be honest I don't see any fundamental difference between your first attempt and the improvement: both share the fact that the mutation of the state happens within the draw function. So in both cases, you have a temporal coupling between updating the state of the app and rendering a new view of the app's state. Yes, what's happening in both cases is very similar, but the function draw in the functional style, in my opinion, is easier to read and maybe it's also easier to test. I would suggest that you don't swap! at all within draw, just deref and render the result of the dereffing. And, in another thread, at potentially a totally different pace than the redrawing's pace, update the application's state accordingly to business rules / constraints. Schematically, something like this: (def app-state (atom (init-state))) (defn draw [...] (let [app-snapshot (deref app-state)] ... call quil primitives to render the application state snapshot ...)) (future ... logic which updates the app-state atom depending on business rules / constraints, in a separate thread ...) I never worked with future, this is exciting, but I have some questions. Do you mean that future is completely separate from draw? I'm just getting started, but draw is not only a function to draw, but as a side effect is the clock of the app, as it's called according to the set frames per second and you normally *take a step* en each draw. Would draw create these futures for the next draw? -- 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: More functional Quil
2014-03-09 14:21 GMT+01:00 J. Pablo Fernández pup...@pupeno.com: On Sunday, March 9, 2014 1:02:52 PM UTC, Laurent PETIT wrote: Hello, To be honest I don't see any fundamental difference between your first attempt and the improvement: both share the fact that the mutation of the state happens within the draw function. So in both cases, you have a temporal coupling between updating the state of the app and rendering a new view of the app's state. Yes, what's happening in both cases is very similar, but the function draw in the functional style, in my opinion, is easier to read and maybe it's also easier to test. I would suggest that you don't swap! at all within draw, just deref and render the result of the dereffing. And, in another thread, at potentially a totally different pace than the redrawing's pace, update the application's state accordingly to business rules / constraints. Schematically, something like this: (def app-state (atom (init-state))) (defn draw [...] (let [app-snapshot (deref app-state)] ... call quil primitives to render the application state snapshot ...)) (future ... logic which updates the app-state atom depending on business rules / constraints, in a separate thread ...) I never worked with future, this is exciting, but I have some questions. Do you mean that future is completely separate from draw? I'm just getting started, but draw is not only a function to draw, but as a side effect is the clock of the app, as it's called according to the set frames per second and you normally *take a step* en each draw. Would draw create these futures for the next draw? future is just a detail in what I was trying to explain. If your logic ties the frame rate and the stepping function, then forget about what I was suggesting. You just will have to ensure that all your logic+rendering time is below the app's clock rate, of course. -- 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. -- 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: More functional Quil
Hi Pablo You can find similar old thread on Quil github repo: https://github.com/quil/quil/pull/19 It may serve as good background what other people considered to make Quil more functional-style. I like your suggestion though I would split your :draw function to 2 fns: an :update function, which only purpose is to update state and :draw which draws state and doesn't change the world at all. If this approach is implemented - other handler functions like :mouse-move, :key-pressed are also need to become update-like functions - they should take state as argument and return new state. The only problem is that it is not backward compatible at all. But probably we still can do it... We can add option :fun-mode? true (stands for functional-mode) which enables all these changes - :draw takes state as argument, new :update function is added for modifying state, all handlers behave like :update. This option is enabled per-sketch. It requires additional work on Quil internals, but I think it is doable. This option can be implemented in coming quil 2.0 and it would be great feature to have. One more thing we could do to make it more functional-like - pass changed values to handlers directly. Currently when :key-pressed handler is called - no argument is passed to the function and you need to use (key-code) or (raw-key) functions to identify which key was pressed. I think this parameters should be explicitly passed to the function. What do you think? Nikita On Sunday, March 9, 2014 1:21:58 PM UTC, J. Pablo Fernández wrote: On Sunday, March 9, 2014 1:02:52 PM UTC, Laurent PETIT wrote: Hello, To be honest I don't see any fundamental difference between your first attempt and the improvement: both share the fact that the mutation of the state happens within the draw function. So in both cases, you have a temporal coupling between updating the state of the app and rendering a new view of the app's state. Yes, what's happening in both cases is very similar, but the function draw in the functional style, in my opinion, is easier to read and maybe it's also easier to test. I would suggest that you don't swap! at all within draw, just deref and render the result of the dereffing. And, in another thread, at potentially a totally different pace than the redrawing's pace, update the application's state accordingly to business rules / constraints. Schematically, something like this: (def app-state (atom (init-state))) (defn draw [...] (let [app-snapshot (deref app-state)] ... call quil primitives to render the application state snapshot ...)) (future ... logic which updates the app-state atom depending on business rules / constraints, in a separate thread ...) I never worked with future, this is exciting, but I have some questions. Do you mean that future is completely separate from draw? I'm just getting started, but draw is not only a function to draw, but as a side effect is the clock of the app, as it's called according to the set frames per second and you normally *take a step* en each draw. Would draw create these futures for the next draw? -- 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: More functional Quil
FWIW I'm not crazy about these suggestions because they seem to me to be mostly cosmetic, and actually negative if they end up leading to multiple incompatible modes of operation. The Processing model seems to me to be intrinsically imperative, and it's also well-known by lots of people and easy to understand. The current Quil scheme, which provides fairly direct access to Processing's existing model from Clojure, still allows us to write functional-style code for all of the interesting stuff that we do within/between calls to the imperative Processing calls. And it allows one to translate Processing ideas into Quil relatively easily. So I like it like it is :-). -Lee On Mar 9, 2014, at 8:29 PM, Nikita Beloglazov wrote: Hi Pablo You can find similar old thread on Quil github repo: https://github.com/quil/quil/pull/19 It may serve as good background what other people considered to make Quil more functional-style. I like your suggestion though I would split your :draw function to 2 fns: an :update function, which only purpose is to update state and :draw which draws state and doesn't change the world at all. If this approach is implemented - other handler functions like :mouse-move, :key-pressed are also need to become update-like functions - they should take state as argument and return new state. The only problem is that it is not backward compatible at all. But probably we still can do it... We can add option :fun-mode? true (stands for functional-mode) which enables all these changes - :draw takes state as argument, new :update function is added for modifying state, all handlers behave like :update. This option is enabled per-sketch. It requires additional work on Quil internals, but I think it is doable. This option can be implemented in coming quil 2.0 and it would be great feature to have. One more thing we could do to make it more functional-like - pass changed values to handlers directly. Currently when :key-pressed handler is called - no argument is passed to the function and you need to use (key-code) or (raw-key) functions to identify which key was pressed. I think this parameters should be explicitly passed to the function. What do you think? Nikita -- 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: More functional Quil
FWIW, I've got an example of a decoupled update/draw loop here: https://github.com/gtrak/quilltest/blob/master/src/quilltest/balls.clj On Sun, Mar 9, 2014 at 10:16 PM, Lee Spector lspec...@hampshire.edu wrote: FWIW I'm not crazy about these suggestions because they seem to me to be mostly cosmetic, and actually negative if they end up leading to multiple incompatible modes of operation. The Processing model seems to me to be intrinsically imperative, and it's also well-known by lots of people and easy to understand. The current Quil scheme, which provides fairly direct access to Processing's existing model from Clojure, still allows us to write functional-style code for all of the interesting stuff that we do within/between calls to the imperative Processing calls. And it allows one to translate Processing ideas into Quil relatively easily. So I like it like it is :-). -Lee On Mar 9, 2014, at 8:29 PM, Nikita Beloglazov wrote: Hi Pablo You can find similar old thread on Quil github repo: https://github.com/quil/quil/pull/19 It may serve as good background what other people considered to make Quil more functional-style. I like your suggestion though I would split your :draw function to 2 fns: an :update function, which only purpose is to update state and :draw which draws state and doesn't change the world at all. If this approach is implemented - other handler functions like :mouse-move, :key-pressed are also need to become update-like functions - they should take state as argument and return new state. The only problem is that it is not backward compatible at all. But probably we still can do it... We can add option :fun-mode? true (stands for functional-mode) which enables all these changes - :draw takes state as argument, new :update function is added for modifying state, all handlers behave like :update. This option is enabled per-sketch. It requires additional work on Quil internals, but I think it is doable. This option can be implemented in coming quil 2.0 and it would be great feature to have. One more thing we could do to make it more functional-like - pass changed values to handlers directly. Currently when :key-pressed handler is called - no argument is passed to the function and you need to use (key-code) or (raw-key) functions to identify which key was pressed. I think this parameters should be explicitly passed to the function. What do you think? Nikita -- 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. -- 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.