If the core parts of the sketch are functional, and parameterized appropriately, that can mitigate the trouble from global state. The only parts that depend on it are pushed out to the edge.
I do this with processing sketches all the time, by introducing objects that behave like streams or filters.
That said, I'm no clojure programmer.
Two links that might be useful:
- https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell (paywall, sorry)
- http://natureofcode.com/book/chapter-8-fractals/ this is in a similar spirit, though not quite related...Shiffman talks about generating Koch lines via either a recursive function, or a emrecursive data structure.
--
You received this message because you are subscribed to the Google Groups "clj-processing" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clj-processin...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hi David!I have question for you: What kind of problems solved your approach?Because any code (that you write) should solve some problem. Do you think the same?P.S. If you want to using a functional approach. You can write a macro that packing and unpacking global state inside the draw function.But I really don't think that is a good way. Because all is good when you have one, two or three var and all work happend inside draw function.What happend if you have more that 10 vars? Or you want to change sketch state from other place that draw function?How do you propose to solve these problems?
--
Hi David
Thanks for your idea, though it seems to be pretty radical shift from usual quil/processing workflow. And I'm a little bit afraid of partially reimplementing processing as I think it may cause a lot of problems. I would encourage you to experiment with it and if you find it useful for your case - you can prepare pull request or send a link to your repository so we can try it live. Personally for me it looks like a difficult task and I'm not going to invest my time in it right now.
I've had an idea for some time now how to introduce functional-mode to quil and I'm planning to implement/experiment with it in next few days. Main problem (as I see it) with quil non-functional workflow is that you have to handle state in imperative style: on each invocation of draw function you have to update some atom and use updated value to draw something on screen. draw has to do both: update AND draw state. Which doesn't sound right. I want to introduce new update function and change semantics for draw and setup functions a little bit. Here is an example of sketch drawing moving ellipse in new fun-mode:
; new version of setup should return initial state; you can do whatever you want in it, but result of setup will be used as initial state
; here it returns initial coordinates of the ellipse (x, y) = (0, 0)(defn setup []
{:x 0 :y 0}); new version of draw take state explicitly and draws it; it should ONLY draw and not change state
(defn draw [state]
(background 255)
(ellipse (:x state) (:y state) 100 100)); update takes old state, updates it and returns new state
; here it increases x coordinate of the ellipse by 3 and y by 2(defn update [state]
(-> state
(update-in [:x] + 3)
(update-in [:y] + 2)))
(defsketch fun-mode
:size [500 500]
:setup setup
:draw draw
:update update)You can see that logic of how state is actually stored is hidden from the user and she/he can ignore it. Semantics for all keyboard, mouse and other handlers will also be changed in similar way.
The problem we'll face when implement this mode that it is not compatible with old workflow (and sketches). To solve it I want to make it optional. By default old non-functional style will be enabled and if you want to use new fun-mode - enable it explicitly.
As a "side-effect" of implementing fun-mode I'm going to introduce middleware to quil. It will be similar to ring middleware if you're familiar with web-development in clojure. It will allow to create plugins for quil to enhance it functionality without actually changing the library itself. fun-mode will be just an middleware which you can enable.