Re: defmethod inside of a (stuart sierra) component?
I would try to stay away from any nested def's in components (but also in other functions). I'm using component a lot and I never had the need for this. Maybe you can elaborate on why you think you need a multimethod inside the component? Maybe a full example? Cheers, Jeroen On Wed, Feb 25, 2015 at 12:08 PM, Colin Yates colin.ya...@gmail.com wrote: Hi, I have a number of commands flying around which need to be handled. defmulti/defmethod seem a nice answer. The problem is that each command handler will need different collaborators (those with long memories will realise this isn't new ground here ;)). I want to do something like: (ns one) (defmulti handle first) (ns two) (defrecord CommandAHandler [collab-1 collab-2] component/Lifecycle (start [this] (defmethod handle :command-a (collab-1 ...))) I realise that the lifecycle of defmethod doesn't match the component (i.e. stopping can't unregister the defmethod), but my main reservation is that a nested defmethod feels a bit weird. Has anyone done anything like this before? 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.
Idiomatic access to collaborators/services
Hi, I ran into a bit of a brick wall when thinking about how to register to and dispatch to multiple micro-services and it made me realise the underlying tension came from not having peace about a fundamental design decision; how do you access your collaborators. Note: I am specifically talking about 'providers of functionality' as oppose to state. I think everybody agrees that passing state around is a good thing (e.g. *db* is so 90s, (defn my-thing-which-needs-a-db [db] ...) is where it is at). One option is to receive instances of a service (probably some implementation of a defprotocol): (den my-service [service-1 service-2 payload] (some-method service-1) (some-method service-2)) The other is to directly reach into the collaborator's namespace: (den my-service [payload] (service-1-ns/some-function) (service-2-ns/some-function)) (maybe some config is passed into my-service which the other services use. The first approach has a much smaller coupling and makes it much easier to reason about. If there is coupling then it is on the protocol of the collaborator. It is therefore trivial to unit-test as you can stub out the collaborators without redef. It also has echoes of OO services, which might be just fine. The second approach means you don't end up passing collaborators deep down hierarchy graphs (which I haven't run into actually - Clojure tends to have a much 'flatter' graph then Java). It does mean testing etc. requires redefs. My inclination is to go for the first as it seems simpler, but I still have an allergic reaction to using protocols like this (because of the OO trap). This clearly isn't new ground, but I could find surprisingly little blogs and discussion about this. It is also something that only really becomes a problem in the larger scale as well. What do you all do? -- 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.
Road: one clojure web framwork
I create a new web framework using clojure. https://github.com/zhujinxian/road.git It implements a servelet filter, transfer parameters of http request to handler and rendering the results of handler using hiccup lib. you can use like: (defn handler [^Integer x] {:text (str hello world, road goes sucess! x)}) (defn home [req content ^Integer num] {:hiccup home.clj :content (str home content) :num num}) (defroutes app (GET /web-test-0.1.0-SNAPSHOT-standalone handler) (GET /home/:num{\\d+} home)) It like compojure (defroutes app (GET / [] h1Hello World/h1) (route/not-found h1Page not found/h1)), but has more ... -- 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: defmethod inside of a (stuart sierra) component?
Sounds reasonable. Though destructuring a component (I was guessing db etc were fields of this particular component) isn't the same as passing the whole system. I'm guessing that you have a lot bigger system in mind than these few commands. I don't have experience with that approach. I'm curious to see what you'll end up with. Cheers, Jeroen On Wed, Feb 25, 2015 at 2:01 PM, Colin Yates colin.ya...@gmail.com wrote: Yes, I did consider that but didn't like the idea of passing the system around. Also handle-command would need access to the system as well. I am wondering whether simply having a 'registry' component which handlers register themselves with (e.g. a map of {predicate handler}) isn't a way forward and not using defmulti... On 25 February 2015 at 12:51, Jeroen van Dijk jeroentjevand...@gmail.com wrote: So I guess another question is where handle-command is being called. What about providing the component as argument to the multimethod (there are other approaches too depending on your need). So: (defmulti handle-command(fn [component command] (first command))) (defmethod handle-command :add-customer [{:keys [db eventstore} [[_ customer]]] ... ) Isn't something like this enough? Jeroen On Wed, Feb 25, 2015 at 1:34 PM, Colin Yates colin.ya...@gmail.com wrote: Hi Jeroen - sure. I have a gateway which can handle a number of 'commands', let's say: AddCustomerCommand ExportQueryCommand to handle the AddCustomerCommand I need access to a database and an eventstore. To handle ExportQueryCommand I need access to the database, a PDF service and so on. One way of achieving this is (assuming commands are of the form [:command-discriminator payload]: (defmulti handle-command first) (defn add-customer [db eventstore customer] ...) (defrecord AddCustomerComponent [db eventstore] ... (start [this] (defmethod handle-command :add-customer [[_ customer]] (add-customer db eventstore customer))..) (defn export-reports [db pdf-generator] ...) (defrecord ExportQueryCommand [db pdf-generator] ... (start [this] (defmethod handle-command :export-query [[_]] (export-query db pdf-generator))..) and so on. Fundamentally my question is one of dispatching where the target of the dispatch requires collaborators that aren't part of the dispatch payload. Does that clarify? On 25 February 2015 at 12:11, Jeroen van Dijk jeroentjevand...@gmail.com wrote: I would try to stay away from any nested def's in components (but also in other functions). I'm using component a lot and I never had the need for this. Maybe you can elaborate on why you think you need a multimethod inside the component? Maybe a full example? Cheers, Jeroen On Wed, Feb 25, 2015 at 12:08 PM, Colin Yates colin.ya...@gmail.com wrote: Hi, I have a number of commands flying around which need to be handled. defmulti/defmethod seem a nice answer. The problem is that each command handler will need different collaborators (those with long memories will realise this isn't new ground here ;)). I want to do something like: (ns one) (defmulti handle first) (ns two) (defrecord CommandAHandler [collab-1 collab-2] component/Lifecycle (start [this] (defmethod handle :command-a (collab-1 ...))) I realise that the lifecycle of defmethod doesn't match the component (i.e. stopping can't unregister the defmethod), but my main reservation is that a nested defmethod feels a bit weird. Has anyone done anything like this before? 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
Re: Idiomatic access to collaborators/services
Having tried few other ways earlier, I now prefer the `first` approach you described. Protocols decouple the contract and the implementation very well, and can be reified for various profiles (unit tests, scenario tests, integration etc.) For constructing the graph I have found Prismatic graph with reifying-functions to be very apt -- you may still need to borrow the lifecycle idea from Stuart Sierra's component (maybe define IStoppable) for things that need shutdown, such as custom thread-pools. Shantanu On Wednesday, 25 February 2015 18:52:28 UTC+5:30, Colin Yates wrote: Hi, I ran into a bit of a brick wall when thinking about how to register to and dispatch to multiple micro-services and it made me realise the underlying tension came from not having peace about a fundamental design decision; how do you access your collaborators. Note: I am specifically talking about 'providers of functionality' as oppose to state. I think everybody agrees that passing state around is a good thing (e.g. *db* is so 90s, (defn my-thing-which-needs-a-db [db] ...) is where it is at). One option is to receive instances of a service (probably some implementation of a defprotocol): (den my-service [service-1 service-2 payload] (some-method service-1) (some-method service-2)) The other is to directly reach into the collaborator's namespace: (den my-service [payload] (service-1-ns/some-function) (service-2-ns/some-function)) (maybe some config is passed into my-service which the other services use. The first approach has a much smaller coupling and makes it much easier to reason about. If there is coupling then it is on the protocol of the collaborator. It is therefore trivial to unit-test as you can stub out the collaborators without redef. It also has echoes of OO services, which might be just fine. The second approach means you don't end up passing collaborators deep down hierarchy graphs (which I haven't run into actually - Clojure tends to have a much 'flatter' graph then Java). It does mean testing etc. requires redefs. My inclination is to go for the first as it seems simpler, but I still have an allergic reaction to using protocols like this (because of the OO trap). This clearly isn't new ground, but I could find surprisingly little blogs and discussion about this. It is also something that only really becomes a problem in the larger scale as well. What do you all do? -- 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: defmethod inside of a (stuart sierra) component?
Hi Jeroen - sure. I have a gateway which can handle a number of 'commands', let's say: AddCustomerCommand ExportQueryCommand to handle the AddCustomerCommand I need access to a database and an eventstore. To handle ExportQueryCommand I need access to the database, a PDF service and so on. One way of achieving this is (assuming commands are of the form [:command-discriminator payload]: (defmulti handle-command first) (defn add-customer [db eventstore customer] ...) (defrecord AddCustomerComponent [db eventstore] ... (start [this] (defmethod handle-command :add-customer [[_ customer]] (add-customer db eventstore customer))..) (defn export-reports [db pdf-generator] ...) (defrecord ExportQueryCommand [db pdf-generator] ... (start [this] (defmethod handle-command :export-query [[_]] (export-query db pdf-generator))..) and so on. Fundamentally my question is one of dispatching where the target of the dispatch requires collaborators that aren't part of the dispatch payload. Does that clarify? On 25 February 2015 at 12:11, Jeroen van Dijk jeroentjevand...@gmail.com wrote: I would try to stay away from any nested def's in components (but also in other functions). I'm using component a lot and I never had the need for this. Maybe you can elaborate on why you think you need a multimethod inside the component? Maybe a full example? Cheers, Jeroen On Wed, Feb 25, 2015 at 12:08 PM, Colin Yates colin.ya...@gmail.com wrote: Hi, I have a number of commands flying around which need to be handled. defmulti/defmethod seem a nice answer. The problem is that each command handler will need different collaborators (those with long memories will realise this isn't new ground here ;)). I want to do something like: (ns one) (defmulti handle first) (ns two) (defrecord CommandAHandler [collab-1 collab-2] component/Lifecycle (start [this] (defmethod handle :command-a (collab-1 ...))) I realise that the lifecycle of defmethod doesn't match the component (i.e. stopping can't unregister the defmethod), but my main reservation is that a nested defmethod feels a bit weird. Has anyone done anything like this before? 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. -- 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: defmethod inside of a (stuart sierra) component?
Hi Colin, Nesting defmethod in the start fn of the Component does have a bad smell. This actually seems counter to the intention of Component, which is to make these dependencies explicit and external. I might do it like this: 1. Create a pure implementation using Component as it was intended. 2. Stash the system map in an atom at startup 3. Write some convenience functions with are the lower-arity versions, and use the system in the atom for the missing arguments. Might be a good place to use a macro if you're doing lots of these. This way, you have isolated the friendly (but less pure) API from the core system. You can still fall back to the versions of the functions which have explicit deps, which could be useful for testing and other scenarios. Example: ; define your components and system ... ; Tuck the system in here at startup (defonce system (atom nil)) (defmulti handle-command first) (defn add-customer [db eventstore customer] ...) ; Convenience function that pulls system from an atom (defn add-customer [customer] (add-customer (@system :db) (@system eventstore) customer)) (defmethod handle-command :add-customer [[_ customer]] (add-customer customer)) (defn export-query [db pdf-generator] ...) ; Convenience function that pulls system from an atom (defn export-query [] (export-query (@system :db) (@system :pdf-generator))) (defmethod handle-command :export-query [[_]] (export-query)) marc On Wed, Feb 25, 2015 at 8:23 AM, Colin Yates colin.ya...@gmail.com wrote: Not as curious as me! Naval gazing is happening right now :). I realised this is part of a bigger question: https://groups.google.com/d/msg/clojure/C3mYu9fMXec/gGUF5rhhZfwJ On 25 February 2015 at 13:19, Jeroen van Dijk jeroentjevand...@gmail.com wrote: Sounds reasonable. Though destructuring a component (I was guessing db etc were fields of this particular component) isn't the same as passing the whole system. I'm guessing that you have a lot bigger system in mind than these few commands. I don't have experience with that approach. I'm curious to see what you'll end up with. Cheers, Jeroen On Wed, Feb 25, 2015 at 2:01 PM, Colin Yates colin.ya...@gmail.com wrote: Yes, I did consider that but didn't like the idea of passing the system around. Also handle-command would need access to the system as well. I am wondering whether simply having a 'registry' component which handlers register themselves with (e.g. a map of {predicate handler}) isn't a way forward and not using defmulti... On 25 February 2015 at 12:51, Jeroen van Dijk jeroentjevand...@gmail.com wrote: So I guess another question is where handle-command is being called. What about providing the component as argument to the multimethod (there are other approaches too depending on your need). So: (defmulti handle-command(fn [component command] (first command))) (defmethod handle-command :add-customer [{:keys [db eventstore} [[_ customer]]] ... ) Isn't something like this enough? Jeroen On Wed, Feb 25, 2015 at 1:34 PM, Colin Yates colin.ya...@gmail.com wrote: Hi Jeroen - sure. I have a gateway which can handle a number of 'commands', let's say: AddCustomerCommand ExportQueryCommand to handle the AddCustomerCommand I need access to a database and an eventstore. To handle ExportQueryCommand I need access to the database, a PDF service and so on. One way of achieving this is (assuming commands are of the form [:command-discriminator payload]: (defmulti handle-command first) (defn add-customer [db eventstore customer] ...) (defrecord AddCustomerComponent [db eventstore] ... (start [this] (defmethod handle-command :add-customer [[_ customer]] (add-customer db eventstore customer))..) (defn export-reports [db pdf-generator] ...) (defrecord ExportQueryCommand [db pdf-generator] ... (start [this] (defmethod handle-command :export-query [[_]] (export-query db pdf-generator))..) and so on. Fundamentally my question is one of dispatching where the target of the dispatch requires collaborators that aren't part of the dispatch payload. Does that clarify? On 25 February 2015 at 12:11, Jeroen van Dijk jeroentjevand...@gmail.com wrote: I would try to stay away from any nested def's in components (but also in other functions). I'm using component a lot and I never had the need for this. Maybe you can elaborate on why you think you need a multimethod inside the component? Maybe a full example? Cheers, Jeroen On Wed, Feb 25, 2015 at 12:08 PM, Colin Yates colin.ya...@gmail.com wrote: Hi, I have a number of commands flying around which need to be handled. defmulti/defmethod seem a nice answer. The problem is that each command
Re: defmethod inside of a (stuart sierra) component?
Yes, I did consider that but didn't like the idea of passing the system around. Also handle-command would need access to the system as well. I am wondering whether simply having a 'registry' component which handlers register themselves with (e.g. a map of {predicate handler}) isn't a way forward and not using defmulti... On 25 February 2015 at 12:51, Jeroen van Dijk jeroentjevand...@gmail.com wrote: So I guess another question is where handle-command is being called. What about providing the component as argument to the multimethod (there are other approaches too depending on your need). So: (defmulti handle-command(fn [component command] (first command))) (defmethod handle-command :add-customer [{:keys [db eventstore} [[_ customer]]] ... ) Isn't something like this enough? Jeroen On Wed, Feb 25, 2015 at 1:34 PM, Colin Yates colin.ya...@gmail.com wrote: Hi Jeroen - sure. I have a gateway which can handle a number of 'commands', let's say: AddCustomerCommand ExportQueryCommand to handle the AddCustomerCommand I need access to a database and an eventstore. To handle ExportQueryCommand I need access to the database, a PDF service and so on. One way of achieving this is (assuming commands are of the form [:command-discriminator payload]: (defmulti handle-command first) (defn add-customer [db eventstore customer] ...) (defrecord AddCustomerComponent [db eventstore] ... (start [this] (defmethod handle-command :add-customer [[_ customer]] (add-customer db eventstore customer))..) (defn export-reports [db pdf-generator] ...) (defrecord ExportQueryCommand [db pdf-generator] ... (start [this] (defmethod handle-command :export-query [[_]] (export-query db pdf-generator))..) and so on. Fundamentally my question is one of dispatching where the target of the dispatch requires collaborators that aren't part of the dispatch payload. Does that clarify? On 25 February 2015 at 12:11, Jeroen van Dijk jeroentjevand...@gmail.com wrote: I would try to stay away from any nested def's in components (but also in other functions). I'm using component a lot and I never had the need for this. Maybe you can elaborate on why you think you need a multimethod inside the component? Maybe a full example? Cheers, Jeroen On Wed, Feb 25, 2015 at 12:08 PM, Colin Yates colin.ya...@gmail.com wrote: Hi, I have a number of commands flying around which need to be handled. defmulti/defmethod seem a nice answer. The problem is that each command handler will need different collaborators (those with long memories will realise this isn't new ground here ;)). I want to do something like: (ns one) (defmulti handle first) (ns two) (defrecord CommandAHandler [collab-1 collab-2] component/Lifecycle (start [this] (defmethod handle :command-a (collab-1 ...))) I realise that the lifecycle of defmethod doesn't match the component (i.e. stopping can't unregister the defmethod), but my main reservation is that a nested defmethod feels a bit weird. Has anyone done anything like this before? 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. -- 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
Re: defmethod inside of a (stuart sierra) component?
Not as curious as me! Naval gazing is happening right now :). I realised this is part of a bigger question: https://groups.google.com/d/msg/clojure/C3mYu9fMXec/gGUF5rhhZfwJ On 25 February 2015 at 13:19, Jeroen van Dijk jeroentjevand...@gmail.com wrote: Sounds reasonable. Though destructuring a component (I was guessing db etc were fields of this particular component) isn't the same as passing the whole system. I'm guessing that you have a lot bigger system in mind than these few commands. I don't have experience with that approach. I'm curious to see what you'll end up with. Cheers, Jeroen On Wed, Feb 25, 2015 at 2:01 PM, Colin Yates colin.ya...@gmail.com wrote: Yes, I did consider that but didn't like the idea of passing the system around. Also handle-command would need access to the system as well. I am wondering whether simply having a 'registry' component which handlers register themselves with (e.g. a map of {predicate handler}) isn't a way forward and not using defmulti... On 25 February 2015 at 12:51, Jeroen van Dijk jeroentjevand...@gmail.com wrote: So I guess another question is where handle-command is being called. What about providing the component as argument to the multimethod (there are other approaches too depending on your need). So: (defmulti handle-command(fn [component command] (first command))) (defmethod handle-command :add-customer [{:keys [db eventstore} [[_ customer]]] ... ) Isn't something like this enough? Jeroen On Wed, Feb 25, 2015 at 1:34 PM, Colin Yates colin.ya...@gmail.com wrote: Hi Jeroen - sure. I have a gateway which can handle a number of 'commands', let's say: AddCustomerCommand ExportQueryCommand to handle the AddCustomerCommand I need access to a database and an eventstore. To handle ExportQueryCommand I need access to the database, a PDF service and so on. One way of achieving this is (assuming commands are of the form [:command-discriminator payload]: (defmulti handle-command first) (defn add-customer [db eventstore customer] ...) (defrecord AddCustomerComponent [db eventstore] ... (start [this] (defmethod handle-command :add-customer [[_ customer]] (add-customer db eventstore customer))..) (defn export-reports [db pdf-generator] ...) (defrecord ExportQueryCommand [db pdf-generator] ... (start [this] (defmethod handle-command :export-query [[_]] (export-query db pdf-generator))..) and so on. Fundamentally my question is one of dispatching where the target of the dispatch requires collaborators that aren't part of the dispatch payload. Does that clarify? On 25 February 2015 at 12:11, Jeroen van Dijk jeroentjevand...@gmail.com wrote: I would try to stay away from any nested def's in components (but also in other functions). I'm using component a lot and I never had the need for this. Maybe you can elaborate on why you think you need a multimethod inside the component? Maybe a full example? Cheers, Jeroen On Wed, Feb 25, 2015 at 12:08 PM, Colin Yates colin.ya...@gmail.com wrote: Hi, I have a number of commands flying around which need to be handled. defmulti/defmethod seem a nice answer. The problem is that each command handler will need different collaborators (those with long memories will realise this isn't new ground here ;)). I want to do something like: (ns one) (defmulti handle first) (ns two) (defrecord CommandAHandler [collab-1 collab-2] component/Lifecycle (start [this] (defmethod handle :command-a (collab-1 ...))) I realise that the lifecycle of defmethod doesn't match the component (i.e. stopping can't unregister the defmethod), but my main reservation is that a nested defmethod feels a bit weird. Has anyone done anything like this before? 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
Re: defmethod inside of a (stuart sierra) component?
I see where you are going. You don't actually need to store the system in an atom as it can be directly referenced from reloaded.repl.system, but I get your point (i.e. adapters). Thanks Marc. On 25 February 2015 at 14:26, Marc Limotte mslimo...@gmail.com wrote: Hi Colin, Nesting defmethod in the start fn of the Component does have a bad smell. This actually seems counter to the intention of Component, which is to make these dependencies explicit and external. I might do it like this: 1. Create a pure implementation using Component as it was intended. 2. Stash the system map in an atom at startup 3. Write some convenience functions with are the lower-arity versions, and use the system in the atom for the missing arguments. Might be a good place to use a macro if you're doing lots of these. This way, you have isolated the friendly (but less pure) API from the core system. You can still fall back to the versions of the functions which have explicit deps, which could be useful for testing and other scenarios. Example: ; define your components and system ... ; Tuck the system in here at startup (defonce system (atom nil)) (defmulti handle-command first) (defn add-customer [db eventstore customer] ...) ; Convenience function that pulls system from an atom (defn add-customer [customer] (add-customer (@system :db) (@system eventstore) customer)) (defmethod handle-command :add-customer [[_ customer]] (add-customer customer)) (defn export-query [db pdf-generator] ...) ; Convenience function that pulls system from an atom (defn export-query [] (export-query (@system :db) (@system :pdf-generator))) (defmethod handle-command :export-query [[_]] (export-query)) marc On Wed, Feb 25, 2015 at 8:23 AM, Colin Yates colin.ya...@gmail.com wrote: Not as curious as me! Naval gazing is happening right now :). I realised this is part of a bigger question: https://groups.google.com/d/msg/clojure/C3mYu9fMXec/gGUF5rhhZfwJ On 25 February 2015 at 13:19, Jeroen van Dijk jeroentjevand...@gmail.com wrote: Sounds reasonable. Though destructuring a component (I was guessing db etc were fields of this particular component) isn't the same as passing the whole system. I'm guessing that you have a lot bigger system in mind than these few commands. I don't have experience with that approach. I'm curious to see what you'll end up with. Cheers, Jeroen On Wed, Feb 25, 2015 at 2:01 PM, Colin Yates colin.ya...@gmail.com wrote: Yes, I did consider that but didn't like the idea of passing the system around. Also handle-command would need access to the system as well. I am wondering whether simply having a 'registry' component which handlers register themselves with (e.g. a map of {predicate handler}) isn't a way forward and not using defmulti... On 25 February 2015 at 12:51, Jeroen van Dijk jeroentjevand...@gmail.com wrote: So I guess another question is where handle-command is being called. What about providing the component as argument to the multimethod (there are other approaches too depending on your need). So: (defmulti handle-command(fn [component command] (first command))) (defmethod handle-command :add-customer [{:keys [db eventstore} [[_ customer]]] ... ) Isn't something like this enough? Jeroen On Wed, Feb 25, 2015 at 1:34 PM, Colin Yates colin.ya...@gmail.com wrote: Hi Jeroen - sure. I have a gateway which can handle a number of 'commands', let's say: AddCustomerCommand ExportQueryCommand to handle the AddCustomerCommand I need access to a database and an eventstore. To handle ExportQueryCommand I need access to the database, a PDF service and so on. One way of achieving this is (assuming commands are of the form [:command-discriminator payload]: (defmulti handle-command first) (defn add-customer [db eventstore customer] ...) (defrecord AddCustomerComponent [db eventstore] ... (start [this] (defmethod handle-command :add-customer [[_ customer]] (add-customer db eventstore customer))..) (defn export-reports [db pdf-generator] ...) (defrecord ExportQueryCommand [db pdf-generator] ... (start [this] (defmethod handle-command :export-query [[_]] (export-query db pdf-generator))..) and so on. Fundamentally my question is one of dispatching where the target of the dispatch requires collaborators that aren't part of the dispatch payload. Does that clarify? On 25 February 2015 at 12:11, Jeroen van Dijk jeroentjevand...@gmail.com wrote: I would try to stay away from any nested def's in components (but also in other functions). I'm using component a lot and I never had the need for this. Maybe you can elaborate on why you think you need a multimethod inside the component?
Re: defmethod inside of a (stuart sierra) component?
So I guess another question is where handle-command is being called. What about providing the component as argument to the multimethod (there are other approaches too depending on your need). So: (defmulti handle-command(fn [component command] (first command))) (defmethod handle-command :add-customer [{:keys [db eventstore} [[_ customer]]] ... ) Isn't something like this enough? Jeroen On Wed, Feb 25, 2015 at 1:34 PM, Colin Yates colin.ya...@gmail.com wrote: Hi Jeroen - sure. I have a gateway which can handle a number of 'commands', let's say: AddCustomerCommand ExportQueryCommand to handle the AddCustomerCommand I need access to a database and an eventstore. To handle ExportQueryCommand I need access to the database, a PDF service and so on. One way of achieving this is (assuming commands are of the form [:command-discriminator payload]: (defmulti handle-command first) (defn add-customer [db eventstore customer] ...) (defrecord AddCustomerComponent [db eventstore] ... (start [this] (defmethod handle-command :add-customer [[_ customer]] (add-customer db eventstore customer))..) (defn export-reports [db pdf-generator] ...) (defrecord ExportQueryCommand [db pdf-generator] ... (start [this] (defmethod handle-command :export-query [[_]] (export-query db pdf-generator))..) and so on. Fundamentally my question is one of dispatching where the target of the dispatch requires collaborators that aren't part of the dispatch payload. Does that clarify? On 25 February 2015 at 12:11, Jeroen van Dijk jeroentjevand...@gmail.com wrote: I would try to stay away from any nested def's in components (but also in other functions). I'm using component a lot and I never had the need for this. Maybe you can elaborate on why you think you need a multimethod inside the component? Maybe a full example? Cheers, Jeroen On Wed, Feb 25, 2015 at 12:08 PM, Colin Yates colin.ya...@gmail.com wrote: Hi, I have a number of commands flying around which need to be handled. defmulti/defmethod seem a nice answer. The problem is that each command handler will need different collaborators (those with long memories will realise this isn't new ground here ;)). I want to do something like: (ns one) (defmulti handle first) (ns two) (defrecord CommandAHandler [collab-1 collab-2] component/Lifecycle (start [this] (defmethod handle :command-a (collab-1 ...))) I realise that the lifecycle of defmethod doesn't match the component (i.e. stopping can't unregister the defmethod), but my main reservation is that a nested defmethod feels a bit weird. Has anyone done anything like this before? 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. -- 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
Re: Idiomatic access to collaborators/services
Thanks Shantanu. I am using component but not graph. Although based on their schema library and om-tools I expect it to be pretty nifty :). On 25 February 2015 at 14:32, Shantanu Kumar kumar.shant...@gmail.com wrote: Having tried few other ways earlier, I now prefer the `first` approach you described. Protocols decouple the contract and the implementation very well, and can be reified for various profiles (unit tests, scenario tests, integration etc.) For constructing the graph I have found Prismatic graph with reifying-functions to be very apt -- you may still need to borrow the lifecycle idea from Stuart Sierra's component (maybe define IStoppable) for things that need shutdown, such as custom thread-pools. Shantanu On Wednesday, 25 February 2015 18:52:28 UTC+5:30, Colin Yates wrote: Hi, I ran into a bit of a brick wall when thinking about how to register to and dispatch to multiple micro-services and it made me realise the underlying tension came from not having peace about a fundamental design decision; how do you access your collaborators. Note: I am specifically talking about 'providers of functionality' as oppose to state. I think everybody agrees that passing state around is a good thing (e.g. *db* is so 90s, (defn my-thing-which-needs-a-db [db] ...) is where it is at). One option is to receive instances of a service (probably some implementation of a defprotocol): (den my-service [service-1 service-2 payload] (some-method service-1) (some-method service-2)) The other is to directly reach into the collaborator's namespace: (den my-service [payload] (service-1-ns/some-function) (service-2-ns/some-function)) (maybe some config is passed into my-service which the other services use. The first approach has a much smaller coupling and makes it much easier to reason about. If there is coupling then it is on the protocol of the collaborator. It is therefore trivial to unit-test as you can stub out the collaborators without redef. It also has echoes of OO services, which might be just fine. The second approach means you don't end up passing collaborators deep down hierarchy graphs (which I haven't run into actually - Clojure tends to have a much 'flatter' graph then Java). It does mean testing etc. requires redefs. My inclination is to go for the first as it seems simpler, but I still have an allergic reaction to using protocols like this (because of the OO trap). This clearly isn't new ground, but I could find surprisingly little blogs and discussion about this. It is also something that only really becomes a problem in the larger scale as well. What do you all do? -- 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: [ANN] thi.ng collection update (CLJ/CLJS)
Hey Karsten, Really glad to see you've been continuing the awesome work here! I used toxiclibs extensively when I first starting programming in processing and it was hugely influential for me! I've been drifting away from computational design since then but I'm hoping to get some serious time to play with your clojure work soon. Best Dylan On Wednesday, February 25, 2015 at 12:07:01 AM UTC-5, Karsten Schmidt wrote: Hi guys, thi.ng is a collection of over a dozen largely x-platform Clojure Clojurescript libs for computational/generative design data visualization tasks. I just wanted to give a little heads up that this project has recently seen a number of releases and, as a whole, by now is generally quite stable and usable (*is used*) for realworld projects (although most libs remain in constant parallel development to make them more feature complete). I've collated a number of images of projects and links to the most important libs here: http://thi.ng/ Most notably of those: http://thi.ng/geom By far the largest sub-project and backbone for most others: A 2D/3D geometry package w/ comprehensive vector algebra, swizzling, intersections, matrix types helpers, quaternions, pure shape primitives with ~50 protocols for polymorphic enquiry manipulation, meshes (incl. I/O), mesh subdivisions, CSG mesh ops, Verlet physics engine (only particles, springs, behaviors)... Most of this lib is pure geometry w/ no rendering specifics, although there're separate modules for SVG rendering w/ shader support decorators [1], WebGL wrapper and converters from shapes/meshes to VBOs and various shader presets/utils. http://thi.ng/shadergraph GLSL (WebGL) pure function library dependency graph (based on com.stuartsierra/dependency), GLSL minification during CLJS compile time http://thi.ng/color RGB, HSV, CMYK, CSS conversions, color presets (incl. D3 category schemes) http://thi.ng/luxor Complete scene compiler DSL for http://luxrender.net, based around thi.ng/geom http://thi.ng/morphogen Declarative 3D form evolution through tree-based transformations, basically an AST generator of geometric operations to transform a single seed node into complex 3D objects http://thi.ng/tweeny Interpolation of nested (presumably animation related) data structures. Allows tweening of deeply nested maps/vectors with completely flexible tween fns/targets and hence easy definition of complex timelines http://thi.ng/validate Purely functional, composable data validation optional corrections for nested data. Supports both maps vectors, wildcards, comes with many predefined validators, but extensible... http://thi.ng/trio A generic, non-RDF specific triple store API and feature rich SPARQL-like query engine (and my prime example of using the literate programming approach with org-mode[2][3]) Last but not least: Super special thanks are due to the following people: Rich, Alex + rest of clojure.core David (+everyone else involved) for the immense effort on making CLJS proper useful, Chas, Kevin and anyone else working on CLJX... none of this would have been possible without these amazing tools! Best, K. Ps. There're a number of other libs in this collection which are in dire need of updating (last touched spring 2013) - these are related to general OpenCL functionality and voxel rendering. Some of the example images on the above site were created with these... [1] https://github.com/thi-ng/geom/blob/master/geom-svg/src/examples.org [2] https://github.com/thi-ng/trio/blob/master/src/query.org [3] http://orgmode.org/ -- Karsten Schmidt http://postspectacular.com | http://thi.ng/ -- 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: Border cases for doseq
Oh, and the page of examples for 'for' has more examples of :when and :while that work similarly to doseq, and may be more informative: http://clojuredocs.org/clojure.core/for On Wed, Feb 25, 2015 at 9:14 AM, Andy Fingerhut andy.finger...@gmail.com wrote: doseq does not have anything precisely like C/Java/Perl/etc.'s 'break' or 'continue'. The closest thing might be the :while keyword. You can see some one example of its use near the end of the examples on this page: http://clojuredocs.org/clojure.core/doseq The best way I know to get such behavior is to use Clojure's loop, where if/when/whatever-conditional-statements-you-wish can used to control explicitly to do another loop iteration using recur, or not. Andy On Wed, Feb 25, 2015 at 8:59 AM, Cecil Westerhof cldwester...@gmail.com wrote: At the moment I have the following function: (defn do-show-table [table] (doseq [{:keys [table_name]} (show-tables db-spec)] (when (= (lower-case table) (lower-case table_name)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] (printf format field type null key default)) In this case it is not very important, because the outer sequence will not be very big. But I would like to leave the doseq at the moment that the when is executed. It will be done 0 or 1 times, so after it is done, there is no use in continuing the sequence walk. The second part is that I would like to do an action if it is done 0 times after the doseq. Is this possible? -- Cecil Westerhof -- 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: Idiomatic access to collaborators/services
The question you should be asking is: do I need polymorphism? If the services you're passing in are distinct and not interchangeable, then you can just use functions: (defn my-service [cache queue payload] (cache/store cache payload) (queue/push queue payload)) On the other hand, if the services have some common functionality that can be abstracted, use protocols: (defn my-service [listeners payload] (doseq [l listeners] (listener/deliver l payload))) It's worth noting that protocols methods and functions have the same syntax, so you can easily convert a function into a protocol. For instance, let's say you've written the first example using functions: (defn my-service [cache queue payload] (cache/store cache payload) (queue/push queue payload)) But for testing purposes, you want to be able to overload the queue with a stubbed version. Well, that's no problem; you can just change the queue/push function into a method on a protocol. Any code that uses queue/push will act the same, but now we have different behaviour depending on the configuration. - James On 25 February 2015 at 13:22, Colin Yates colin.ya...@gmail.com wrote: Hi, I ran into a bit of a brick wall when thinking about how to register to and dispatch to multiple micro-services and it made me realise the underlying tension came from not having peace about a fundamental design decision; how do you access your collaborators. Note: I am specifically talking about 'providers of functionality' as oppose to state. I think everybody agrees that passing state around is a good thing (e.g. *db* is so 90s, (defn my-thing-which-needs-a-db [db] ...) is where it is at). One option is to receive instances of a service (probably some implementation of a defprotocol): (den my-service [service-1 service-2 payload] (some-method service-1) (some-method service-2)) The other is to directly reach into the collaborator's namespace: (den my-service [payload] (service-1-ns/some-function) (service-2-ns/some-function)) (maybe some config is passed into my-service which the other services use. The first approach has a much smaller coupling and makes it much easier to reason about. If there is coupling then it is on the protocol of the collaborator. It is therefore trivial to unit-test as you can stub out the collaborators without redef. It also has echoes of OO services, which might be just fine. The second approach means you don't end up passing collaborators deep down hierarchy graphs (which I haven't run into actually - Clojure tends to have a much 'flatter' graph then Java). It does mean testing etc. requires redefs. My inclination is to go for the first as it seems simpler, but I still have an allergic reaction to using protocols like this (because of the OO trap). This clearly isn't new ground, but I could find surprisingly little blogs and discussion about this. It is also something that only really becomes a problem in the larger scale as well. What do you all do? -- 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.
Border cases for doseq
At the moment I have the following function: (defn do-show-table [table] (doseq [{:keys [table_name]} (show-tables db-spec)] (when (= (lower-case table) (lower-case table_name)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] (printf format field type null key default)) In this case it is not very important, because the outer sequence will not be very big. But I would like to leave the doseq at the moment that the when is executed. It will be done 0 or 1 times, so after it is done, there is no use in continuing the sequence walk. The second part is that I would like to do an action if it is done 0 times after the doseq. Is this possible? -- Cecil Westerhof -- 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: Border cases for doseq
doseq does not have anything precisely like C/Java/Perl/etc.'s 'break' or 'continue'. The closest thing might be the :while keyword. You can see some one example of its use near the end of the examples on this page: http://clojuredocs.org/clojure.core/doseq The best way I know to get such behavior is to use Clojure's loop, where if/when/whatever-conditional-statements-you-wish can used to control explicitly to do another loop iteration using recur, or not. Andy On Wed, Feb 25, 2015 at 8:59 AM, Cecil Westerhof cldwester...@gmail.com wrote: At the moment I have the following function: (defn do-show-table [table] (doseq [{:keys [table_name]} (show-tables db-spec)] (when (= (lower-case table) (lower-case table_name)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] (printf format field type null key default)) In this case it is not very important, because the outer sequence will not be very big. But I would like to leave the doseq at the moment that the when is executed. It will be done 0 or 1 times, so after it is done, there is no use in continuing the sequence walk. The second part is that I would like to do an action if it is done 0 times after the doseq. Is this possible? -- Cecil Westerhof -- 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: Border cases for doseq
2015-02-25 18:14 GMT+01:00 Andy Fingerhut andy.finger...@gmail.com: doseq does not have anything precisely like C/Java/Perl/etc.'s 'break' or 'continue'. The closest thing might be the :while keyword. You can see some one example of its use near the end of the examples on this page: http://clojuredocs.org/clojure.core/doseq The best way I know to get such behavior is to use Clojure's loop, where if/when/whatever-conditional-statements-you-wish can used to control explicitly to do another loop iteration using recur, or not. I made the following with loop: (defn do-show-table [table] (loop [all-tables (show-tables db-spec)] (let [this-table (get (first all-tables) :table_name)] (if (= all-tables ()) (printf Table not found: %s\n table) (if (= (lower-case table) (lower-case this-table)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf Table %s:\n table) (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] (printf format field type null key default)) (println)) (recur (rest all-tables))) It solves both problems. On Wed, Feb 25, 2015 at 8:59 AM, Cecil Westerhof cldwester...@gmail.com wrote: At the moment I have the following function: (defn do-show-table [table] (doseq [{:keys [table_name]} (show-tables db-spec)] (when (= (lower-case table) (lower-case table_name)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] (printf format field type null key default)) In this case it is not very important, because the outer sequence will not be very big. But I would like to leave the doseq at the moment that the when is executed. It will be done 0 or 1 times, so after it is done, there is no use in continuing the sequence walk. The second part is that I would like to do an action if it is done 0 times after the doseq. Is this possible? -- Cecil Westerhof -- 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: Idiomatic access to collaborators/services
Hi James, Agreed, and I did feel a little dirty using a protocol simply to satisfy the swap out for testing (when in fact redef isn't *that* bad). I had made a flawed assumption all along that accessing a protocol method was different than a normal function (I though the 'cache' and 'queue' carried their functions with them so (store cache payload) and (push queue payload)). Now I understand they symmetrical it makes a lot more sense, and provides a lot more freedom. On 25 February 2015 at 17:44, James Reeves ja...@booleanknot.com wrote: The question you should be asking is: do I need polymorphism? If the services you're passing in are distinct and not interchangeable, then you can just use functions: (defn my-service [cache queue payload] (cache/store cache payload) (queue/push queue payload)) On the other hand, if the services have some common functionality that can be abstracted, use protocols: (defn my-service [listeners payload] (doseq [l listeners] (listener/deliver l payload))) It's worth noting that protocols methods and functions have the same syntax, so you can easily convert a function into a protocol. For instance, let's say you've written the first example using functions: (defn my-service [cache queue payload] (cache/store cache payload) (queue/push queue payload)) But for testing purposes, you want to be able to overload the queue with a stubbed version. Well, that's no problem; you can just change the queue/push function into a method on a protocol. Any code that uses queue/push will act the same, but now we have different behaviour depending on the configuration. - James On 25 February 2015 at 13:22, Colin Yates colin.ya...@gmail.com wrote: Hi, I ran into a bit of a brick wall when thinking about how to register to and dispatch to multiple micro-services and it made me realise the underlying tension came from not having peace about a fundamental design decision; how do you access your collaborators. Note: I am specifically talking about 'providers of functionality' as oppose to state. I think everybody agrees that passing state around is a good thing (e.g. *db* is so 90s, (defn my-thing-which-needs-a-db [db] ...) is where it is at). One option is to receive instances of a service (probably some implementation of a defprotocol): (den my-service [service-1 service-2 payload] (some-method service-1) (some-method service-2)) The other is to directly reach into the collaborator's namespace: (den my-service [payload] (service-1-ns/some-function) (service-2-ns/some-function)) (maybe some config is passed into my-service which the other services use. The first approach has a much smaller coupling and makes it much easier to reason about. If there is coupling then it is on the protocol of the collaborator. It is therefore trivial to unit-test as you can stub out the collaborators without redef. It also has echoes of OO services, which might be just fine. The second approach means you don't end up passing collaborators deep down hierarchy graphs (which I haven't run into actually - Clojure tends to have a much 'flatter' graph then Java). It does mean testing etc. requires redefs. My inclination is to go for the first as it seems simpler, but I still have an allergic reaction to using protocols like this (because of the OO trap). This clearly isn't new ground, but I could find surprisingly little blogs and discussion about this. It is also something that only really becomes a problem in the larger scale as well. What do you all do? -- 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
Re: Border cases for doseq
2015-02-25 19:23 GMT+01:00 Aaron Cohen aa...@assonance.org: On Wed, Feb 25, 2015 at 1:08 PM, Cecil Westerhof cldwester...@gmail.com wrote: 2015-02-25 18:14 GMT+01:00 Andy Fingerhut andy.finger...@gmail.com: doseq does not have anything precisely like C/Java/Perl/etc.'s 'break' or 'continue'. The closest thing might be the :while keyword. You can see some one example of its use near the end of the examples on this page: http://clojuredocs.org/clojure.core/doseq The best way I know to get such behavior is to use Clojure's loop, where if/when/whatever-conditional-statements-you-wish can used to control explicitly to do another loop iteration using recur, or not. I made the following with loop: (defn do-show-table [table] (loop [all-tables (show-tables db-spec)] (let [this-table (get (first all-tables) :table_name)] (if (= all-tables ()) (printf Table not found: %s\n table) (if (= (lower-case table) (lower-case this-table)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf Table %s:\n table) (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] Please don't get into the habit of doing db queries like this, you're one Little Bobby Tables away from an sql injection. In this case you should do (jdbc/query db-spec [SHOW COLUMNS FROM ? table]). That gives: JdbcSQLException Syntax error in SQL statement SHOW COLUMNS FROM ?; expected identifier; SQL statement: SHOW COLUMNS FROM ? [42001-184] org.h2.engine.SessionRemote.done (SessionRemote.java:622) That is why I do it in this way. As I understood it this has to do with that with a 'show columns from' the table can not be supplied. (I first tried Yesql, only when that did not work I went to JDBC.) I think you would be well-served by a general clojure principle here of trying to get the data you're are dealing within into values as quickly as possible, and then working with those. Rather than inter-mixing your querying and display as you're doing here, I would design this as a query to fill some maps describing your tables, and then use clojure.pprint/print-table to print out the resulting map when desired. This was just a proof of concept to get things working in the REPL. Later on it should be done much neater. (For example a text based version and a GUI version.) (printf format field type null key default)) (println)) (recur (rest all-tables))) It solves both problems. On Wed, Feb 25, 2015 at 8:59 AM, Cecil Westerhof cldwester...@gmail.com wrote: At the moment I have the following function: (defn do-show-table [table] (doseq [{:keys [table_name]} (show-tables db-spec)] (when (= (lower-case table) (lower-case table_name)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] (printf format field type null key default)) In this case it is not very important, because the outer sequence will not be very big. But I would like to leave the doseq at the moment that the when is executed. It will be done 0 or 1 times, so after it is done, there is no use in continuing the sequence walk. The second part is that I would like to do an action if it is done 0 times after the doseq. Is this possible? -- Cecil Westerhof -- 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: How not to drop core.async publication items?
Docstring says Items received when there are no matching subs get dropped. You would have to implement your own version of the Pub interface which caches all messages and broadcasts them all to a newly subscribed channel within sub. Notice that an unlimited cache would imply a possible memory leak. It is highly questionable whether this solution is a good fit for the underlying problem you are trying to solve. It is more likely that it would solve a problem resulting from a synchronization problem which should be solved elsewhere. On Tuesday, February 24, 2015 at 10:51:41 PM UTC+1, Cristian C wrote: My test case would be something like this: ;; I have a channel that I want to wrap in a publication (def publisher (async/chan)) (def publication (async/pub publisher :topic)) ;; then I put data into the publisher channel (async/put! publisher {:topic :foo :payload first message}) ;; then I create a channel to read data from that publication (def reader (async/chan)) (async/sub publication :foo reader) (async/go (println value is: (async/! reader))) ;; nothing happens since the publication already read the value and dropped it ;; if I send another message, this time it will be read by the ! above (async/put! c1 {:topic :foo :msg second message}) == value is {:topic :foo :msg second message} Is there a way not to lose that first item? -- 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: Border cases for doseq
As penance, here's an example that is closer to what I was describing: (require '[clojure.java.jdbc :as j]) (require '[clojure.pprint :as pp]) (def db-spec {:subprotocol derby :classname org.apache.derby.jdbc.EmbeddedDriver :subname testDb :create true}) (j/db-do-commands db-spec (j/create-table-ddl :fruit [:name varchar(32) :primary :key] [:appearance varchar(32)] [:cost :int] [:grade :real])) (j/db-do-commands db-spec (j/create-table-ddl :vegetables [:name varchar(32) :primary :key] [:appearance varchar(32)] [:cost :int] [:grade :real])) ;; Print the columns from all application tables (pp/print-table [:table_name :column_name :type_name :column_size] (j/with-db-metadata [md db-spec] (j/metadata-result (.getColumns md nil APP nil nil - This produces: | :table_name | :column_name | :type_name | :column_size | |-+--++--| | FRUIT | NAME |VARCHAR | 32 | | FRUIT | APPEARANCE |VARCHAR | 32 | | FRUIT | COST |INTEGER | 10 | | FRUIT |GRADE | REAL | 23 | | VEGETABLES | NAME |VARCHAR | 32 | | VEGETABLES | APPEARANCE |VARCHAR | 32 | | VEGETABLES | COST |INTEGER | 10 | | VEGETABLES |GRADE | REAL | 23 | On Wed, Feb 25, 2015 at 1:41 PM, Aaron Cohen aa...@assonance.org wrote: On Wed, Feb 25, 2015 at 1:35 PM, Cecil Westerhof cldwester...@gmail.com wrote: 2015-02-25 19:23 GMT+01:00 Aaron Cohen aa...@assonance.org: On Wed, Feb 25, 2015 at 1:08 PM, Cecil Westerhof cldwester...@gmail.com wrote: 2015-02-25 18:14 GMT+01:00 Andy Fingerhut andy.finger...@gmail.com: doseq does not have anything precisely like C/Java/Perl/etc.'s 'break' or 'continue'. The closest thing might be the :while keyword. You can see some one example of its use near the end of the examples on this page: http://clojuredocs.org/clojure.core/doseq The best way I know to get such behavior is to use Clojure's loop, where if/when/whatever-conditional-statements-you-wish can used to control explicitly to do another loop iteration using recur, or not. I made the following with loop: (defn do-show-table [table] (loop [all-tables (show-tables db-spec)] (let [this-table (get (first all-tables) :table_name)] (if (= all-tables ()) (printf Table not found: %s\n table) (if (= (lower-case table) (lower-case this-table)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf Table %s:\n table) (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] Please don't get into the habit of doing db queries like this, you're one Little Bobby Tables away from an sql injection. In this case you should do (jdbc/query db-spec [SHOW COLUMNS FROM ? table]). That gives: JdbcSQLException Syntax error in SQL statement SHOW COLUMNS FROM ?; expected identifier; SQL statement: SHOW COLUMNS FROM ? [42001-184] org.h2.engine.SessionRemote.done (SessionRemote.java:622) That is why I do it in this way. As I understood it this has to do with that with a 'show columns from' the table can not be supplied. (I first tried Yesql, only when that did not work I went to JDBC.) I see, sorry to jump the gun and be incorrect while doing so. -- 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: Border cases for doseq
Another way to structure this problem is as sequences: 1. Start with a sequence of tables. (show-tables db-spec) 2. Filter down to only the tables you care about. (filter my-pred tables-seq) 3. Take only the first of these. (take 1 filtered-tables-seq) 4. If there is a table, do your side effects with it. (doseq [t 0-or-1-filtered-tables] (...)) That way, you will only do the work zero or one times, but the depth of your code is much shallower, and easier to read. e On Wed, Feb 25, 2015 at 1:35 PM, Cecil Westerhof cldwester...@gmail.com wrote: 2015-02-25 19:23 GMT+01:00 Aaron Cohen aa...@assonance.org: On Wed, Feb 25, 2015 at 1:08 PM, Cecil Westerhof cldwester...@gmail.com wrote: 2015-02-25 18:14 GMT+01:00 Andy Fingerhut andy.finger...@gmail.com: doseq does not have anything precisely like C/Java/Perl/etc.'s 'break' or 'continue'. The closest thing might be the :while keyword. You can see some one example of its use near the end of the examples on this page: http://clojuredocs.org/clojure.core/doseq The best way I know to get such behavior is to use Clojure's loop, where if/when/whatever-conditional-statements-you-wish can used to control explicitly to do another loop iteration using recur, or not. I made the following with loop: (defn do-show-table [table] (loop [all-tables (show-tables db-spec)] (let [this-table (get (first all-tables) :table_name)] (if (= all-tables ()) (printf Table not found: %s\n table) (if (= (lower-case table) (lower-case this-table)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf Table %s:\n table) (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] Please don't get into the habit of doing db queries like this, you're one Little Bobby Tables away from an sql injection. In this case you should do (jdbc/query db-spec [SHOW COLUMNS FROM ? table]). That gives: JdbcSQLException Syntax error in SQL statement SHOW COLUMNS FROM ?; expected identifier; SQL statement: SHOW COLUMNS FROM ? [42001-184] org.h2.engine.SessionRemote.done (SessionRemote.java:622) That is why I do it in this way. As I understood it this has to do with that with a 'show columns from' the table can not be supplied. (I first tried Yesql, only when that did not work I went to JDBC.) I think you would be well-served by a general clojure principle here of trying to get the data you're are dealing within into values as quickly as possible, and then working with those. Rather than inter-mixing your querying and display as you're doing here, I would design this as a query to fill some maps describing your tables, and then use clojure.pprint/print-table to print out the resulting map when desired. This was just a proof of concept to get things working in the REPL. Later on it should be done much neater. (For example a text based version and a GUI version.) (printf format field type null key default)) (println)) (recur (rest all-tables))) It solves both problems. On Wed, Feb 25, 2015 at 8:59 AM, Cecil Westerhof cldwester...@gmail.com wrote: At the moment I have the following function: (defn do-show-table [table] (doseq [{:keys [table_name]} (show-tables db-spec)] (when (= (lower-case table) (lower-case table_name)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] (printf format field type null key default)) In this case it is not very important, because the outer sequence will not be very big. But I would like to leave the doseq at the moment that the when is executed. It will be done 0 or 1 times, so after it is done, there is no use in continuing the sequence walk. The second part is that I would like to do an action if it is done 0 times after the doseq. Is this possible? -- Cecil Westerhof -- 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
Re: Border cases for doseq
On Wed, Feb 25, 2015 at 1:35 PM, Cecil Westerhof cldwester...@gmail.com wrote: 2015-02-25 19:23 GMT+01:00 Aaron Cohen aa...@assonance.org: On Wed, Feb 25, 2015 at 1:08 PM, Cecil Westerhof cldwester...@gmail.com wrote: 2015-02-25 18:14 GMT+01:00 Andy Fingerhut andy.finger...@gmail.com: doseq does not have anything precisely like C/Java/Perl/etc.'s 'break' or 'continue'. The closest thing might be the :while keyword. You can see some one example of its use near the end of the examples on this page: http://clojuredocs.org/clojure.core/doseq The best way I know to get such behavior is to use Clojure's loop, where if/when/whatever-conditional-statements-you-wish can used to control explicitly to do another loop iteration using recur, or not. I made the following with loop: (defn do-show-table [table] (loop [all-tables (show-tables db-spec)] (let [this-table (get (first all-tables) :table_name)] (if (= all-tables ()) (printf Table not found: %s\n table) (if (= (lower-case table) (lower-case this-table)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf Table %s:\n table) (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] Please don't get into the habit of doing db queries like this, you're one Little Bobby Tables away from an sql injection. In this case you should do (jdbc/query db-spec [SHOW COLUMNS FROM ? table]). That gives: JdbcSQLException Syntax error in SQL statement SHOW COLUMNS FROM ?; expected identifier; SQL statement: SHOW COLUMNS FROM ? [42001-184] org.h2.engine.SessionRemote.done (SessionRemote.java:622) That is why I do it in this way. As I understood it this has to do with that with a 'show columns from' the table can not be supplied. (I first tried Yesql, only when that did not work I went to JDBC.) I see, sorry to jump the gun and be incorrect while doing so. -- 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: Border cases for doseq
Cecil, Have you looked at the community documentation for java.jdbc? It has some examples of DDL and metadata: http://clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl.html http://clojure-doc.org/articles/ecosystem/java_jdbc/using_ddl.html Sean On Feb 25, 2015, at 10:35 AM, Cecil Westerhof cldwester...@gmail.com wrote: That is why I do it in this way. As I understood it this has to do with that with a 'show columns from' the table can not be supplied. (I first tried Yesql, only when that did not work I went to JDBC.) -- 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: Border cases for doseq
On Wed, Feb 25, 2015 at 1:08 PM, Cecil Westerhof cldwester...@gmail.com wrote: 2015-02-25 18:14 GMT+01:00 Andy Fingerhut andy.finger...@gmail.com: doseq does not have anything precisely like C/Java/Perl/etc.'s 'break' or 'continue'. The closest thing might be the :while keyword. You can see some one example of its use near the end of the examples on this page: http://clojuredocs.org/clojure.core/doseq The best way I know to get such behavior is to use Clojure's loop, where if/when/whatever-conditional-statements-you-wish can used to control explicitly to do another loop iteration using recur, or not. I made the following with loop: (defn do-show-table [table] (loop [all-tables (show-tables db-spec)] (let [this-table (get (first all-tables) :table_name)] (if (= all-tables ()) (printf Table not found: %s\n table) (if (= (lower-case table) (lower-case this-table)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf Table %s:\n table) (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] Please don't get into the habit of doing db queries like this, you're one Little Bobby Tables away from an sql injection. In this case you should do (jdbc/query db-spec [SHOW COLUMNS FROM ? table]). I think you would be well-served by a general clojure principle here of trying to get the data you're are dealing within into values as quickly as possible, and then working with those. Rather than inter-mixing your querying and display as you're doing here, I would design this as a query to fill some maps describing your tables, and then use clojure.pprint/print-table to print out the resulting map when desired. --Aaron (printf format field type null key default)) (println)) (recur (rest all-tables))) It solves both problems. On Wed, Feb 25, 2015 at 8:59 AM, Cecil Westerhof cldwester...@gmail.com wrote: At the moment I have the following function: (defn do-show-table [table] (doseq [{:keys [table_name]} (show-tables db-spec)] (when (= (lower-case table) (lower-case table_name)) (let [format %-20s %-30s %-5s %-5s %-20s\n] (printf format Field Type Null? Key Default) (doseq [{:keys [field type null key default]} (jdbc/query db-spec [(str SHOW COLUMNS FROM table)])] (printf format field type null key default)) In this case it is not very important, because the outer sequence will not be very big. But I would like to leave the doseq at the moment that the when is executed. It will be done 0 or 1 times, so after it is done, there is no use in continuing the sequence walk. The second part is that I would like to do an action if it is done 0 times after the doseq. Is this possible? -- Cecil Westerhof -- 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.
[ANN] thi.ng collection update (CLJ/CLJS)
This is incredible work. Thanks for sharing! -- 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: [ClojureScript] [ANN] thi.ng collection update (CLJ/CLJS)
So... what is computational design? I've been using OpenSCAD to make models for 3D printing, and I keep wishing for a Clojure syntax and real functions and things. Is this it? (It doesn't seem to have constructive solid geometry for things which aren't meshes.) -Jason On Wed, Feb 25, 2015 at 4:13 PM, Karsten Schmidt i...@toxi.co.uk wrote: That's a good point, Bruce! To be honest, I don't know anymore, but it makes complete sense to change it. Consider it done! :) As for your mapping question, yes, of course! I've done a few of them. E.g. the first pic on the website [1] was a project for The ODI in 2013 and is a map of different council/borough stats of London (here knife crime). The shape files were first retrieved processed with the thi.ng/trio lib directly from the UK statistics office's SPARQL endpoint [2], then projected to Mercator, converted to 2d polygons, smoothed them and then extruded as 3D walled meshes and exported as STL files using geom. To create that rendered image, another function then combined all borough meshes into a complete render scene for Luxrender (using the luxor lib). Since this all was for a 60sec animation, I also wrote the tweeny lib for that project to allow me to define the timeline for the various camera, mesh, light shader changes. The whole bundle was then sent to EC2 and rendered on 340+ CPUs... basically, spawned a private render farm. Alternatively with 30 lines of code you could query any UK constituency (or use similar endpoints for other countries), do those initial shape transformations and send the resulting STL mesh file straight to a 3D printer... For online use, of course the SVG or WebGL modules would be more interesting, but these really would just deal with that last transformation/visualization step, i.e. turning a thi.ng.geom.Polygon2 into an SVG polygon node or tesselate it and stuff it into WebGL buffer to display... For more flexible mapping, it'd be great to port some/all of the projections from [3] in its own clj lib for easier (and non-JS related) access... [1] http://thi.ng/img/04.jpg [2] http://statistics.data.gov.uk/doc/statistical-geography [3] https://github.com/d3/d3-geo-projection/ Hth! On 25 February 2015 at 22:34, Bruce Durling b...@otfrom.com wrote: Karsten, Is there a reason why you went with a README.md and then an index.org rather than a plain README.org? (love all the rest of it and loved your use of it at The Barbican. I need to get my head around it all. I'm wondering if I can use it for some of the geographic and other charting things I do a lot of). cheers, Bruce On Wed, Feb 25, 2015 at 5:06 AM, Karsten Schmidt i...@toxi.co.uk wrote: Hi guys, thi.ng is a collection of over a dozen largely x-platform Clojure Clojurescript libs for computational/generative design data visualization tasks. I just wanted to give a little heads up that this project has recently seen a number of releases and, as a whole, by now is generally quite stable and usable (*is used*) for realworld projects (although most libs remain in constant parallel development to make them more feature complete). I've collated a number of images of projects and links to the most important libs here: http://thi.ng/ Most notably of those: http://thi.ng/geom By far the largest sub-project and backbone for most others: A 2D/3D geometry package w/ comprehensive vector algebra, swizzling, intersections, matrix types helpers, quaternions, pure shape primitives with ~50 protocols for polymorphic enquiry manipulation, meshes (incl. I/O), mesh subdivisions, CSG mesh ops, Verlet physics engine (only particles, springs, behaviors)... Most of this lib is pure geometry w/ no rendering specifics, although there're separate modules for SVG rendering w/ shader support decorators [1], WebGL wrapper and converters from shapes/meshes to VBOs and various shader presets/utils. http://thi.ng/shadergraph GLSL (WebGL) pure function library dependency graph (based on com.stuartsierra/dependency), GLSL minification during CLJS compile time http://thi.ng/color RGB, HSV, CMYK, CSS conversions, color presets (incl. D3 category schemes) http://thi.ng/luxor Complete scene compiler DSL for http://luxrender.net, based around thi.ng/geom http://thi.ng/morphogen Declarative 3D form evolution through tree-based transformations, basically an AST generator of geometric operations to transform a single seed node into complex 3D objects http://thi.ng/tweeny Interpolation of nested (presumably animation related) data structures. Allows tweening of deeply nested maps/vectors with completely flexible tween fns/targets and hence easy definition of complex timelines http://thi.ng/validate Purely functional, composable data validation optional corrections for nested data. Supports both maps vectors, wildcards, comes with many
Re: Is Caribou Dormant ?
Sure looks dormant to me. My usual rule is, if you think you'd feel comfortable maintaining it yourself if it ever became necessary, use it, otherwise look elsewhere. On Wed, Feb 25, 2015 at 3:36 PM Geraldo Lopes de Souza geraldo...@gmail.com wrote: Hi, I'm checking Caribou, and wanna know if anyone is using it. It appears that it is a dormant project by the looks of the last update https://github.com/caribou/caribou Thanks in advance, Geraldo Lopes de Souza -- 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: [ClojureScript] [ANN] thi.ng collection update (CLJ/CLJS)
Karsten, Is there a reason why you went with a README.md and then an index.org rather than a plain README.org? (love all the rest of it and loved your use of it at The Barbican. I need to get my head around it all. I'm wondering if I can use it for some of the geographic and other charting things I do a lot of). cheers, Bruce On Wed, Feb 25, 2015 at 5:06 AM, Karsten Schmidt i...@toxi.co.uk wrote: Hi guys, thi.ng is a collection of over a dozen largely x-platform Clojure Clojurescript libs for computational/generative design data visualization tasks. I just wanted to give a little heads up that this project has recently seen a number of releases and, as a whole, by now is generally quite stable and usable (*is used*) for realworld projects (although most libs remain in constant parallel development to make them more feature complete). I've collated a number of images of projects and links to the most important libs here: http://thi.ng/ Most notably of those: http://thi.ng/geom By far the largest sub-project and backbone for most others: A 2D/3D geometry package w/ comprehensive vector algebra, swizzling, intersections, matrix types helpers, quaternions, pure shape primitives with ~50 protocols for polymorphic enquiry manipulation, meshes (incl. I/O), mesh subdivisions, CSG mesh ops, Verlet physics engine (only particles, springs, behaviors)... Most of this lib is pure geometry w/ no rendering specifics, although there're separate modules for SVG rendering w/ shader support decorators [1], WebGL wrapper and converters from shapes/meshes to VBOs and various shader presets/utils. http://thi.ng/shadergraph GLSL (WebGL) pure function library dependency graph (based on com.stuartsierra/dependency), GLSL minification during CLJS compile time http://thi.ng/color RGB, HSV, CMYK, CSS conversions, color presets (incl. D3 category schemes) http://thi.ng/luxor Complete scene compiler DSL for http://luxrender.net, based around thi.ng/geom http://thi.ng/morphogen Declarative 3D form evolution through tree-based transformations, basically an AST generator of geometric operations to transform a single seed node into complex 3D objects http://thi.ng/tweeny Interpolation of nested (presumably animation related) data structures. Allows tweening of deeply nested maps/vectors with completely flexible tween fns/targets and hence easy definition of complex timelines http://thi.ng/validate Purely functional, composable data validation optional corrections for nested data. Supports both maps vectors, wildcards, comes with many predefined validators, but extensible... http://thi.ng/trio A generic, non-RDF specific triple store API and feature rich SPARQL-like query engine (and my prime example of using the literate programming approach with org-mode[2][3]) Last but not least: Super special thanks are due to the following people: Rich, Alex + rest of clojure.core David (+everyone else involved) for the immense effort on making CLJS proper useful, Chas, Kevin and anyone else working on CLJX... none of this would have been possible without these amazing tools! Best, K. Ps. There're a number of other libs in this collection which are in dire need of updating (last touched spring 2013) - these are related to general OpenCL functionality and voxel rendering. Some of the example images on the above site were created with these... [1] https://github.com/thi-ng/geom/blob/master/geom-svg/src/examples.org [2] https://github.com/thi-ng/trio/blob/master/src/query.org [3] http://orgmode.org/ -- Karsten Schmidt http://postspectacular.com | http://thi.ng/ -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups ClojureScript group. To unsubscribe from this group and stop receiving emails from it, send an email to clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescr...@googlegroups.com. Visit this group at http://groups.google.com/group/clojurescript. -- 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.
Is Caribou Dormant ?
Hi, I'm checking Caribou, and wanna know if anyone is using it. It appears that it is a dormant project by the looks of the last update https://github.com/caribou/caribou Thanks in advance, Geraldo Lopes de Souza -- 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: [ClojureScript] [ANN] thi.ng collection update (CLJ/CLJS)
That's a good point, Bruce! To be honest, I don't know anymore, but it makes complete sense to change it. Consider it done! :) As for your mapping question, yes, of course! I've done a few of them. E.g. the first pic on the website [1] was a project for The ODI in 2013 and is a map of different council/borough stats of London (here knife crime). The shape files were first retrieved processed with the thi.ng/trio lib directly from the UK statistics office's SPARQL endpoint [2], then projected to Mercator, converted to 2d polygons, smoothed them and then extruded as 3D walled meshes and exported as STL files using geom. To create that rendered image, another function then combined all borough meshes into a complete render scene for Luxrender (using the luxor lib). Since this all was for a 60sec animation, I also wrote the tweeny lib for that project to allow me to define the timeline for the various camera, mesh, light shader changes. The whole bundle was then sent to EC2 and rendered on 340+ CPUs... basically, spawned a private render farm. Alternatively with 30 lines of code you could query any UK constituency (or use similar endpoints for other countries), do those initial shape transformations and send the resulting STL mesh file straight to a 3D printer... For online use, of course the SVG or WebGL modules would be more interesting, but these really would just deal with that last transformation/visualization step, i.e. turning a thi.ng.geom.Polygon2 into an SVG polygon node or tesselate it and stuff it into WebGL buffer to display... For more flexible mapping, it'd be great to port some/all of the projections from [3] in its own clj lib for easier (and non-JS related) access... [1] http://thi.ng/img/04.jpg [2] http://statistics.data.gov.uk/doc/statistical-geography [3] https://github.com/d3/d3-geo-projection/ Hth! On 25 February 2015 at 22:34, Bruce Durling b...@otfrom.com wrote: Karsten, Is there a reason why you went with a README.md and then an index.org rather than a plain README.org? (love all the rest of it and loved your use of it at The Barbican. I need to get my head around it all. I'm wondering if I can use it for some of the geographic and other charting things I do a lot of). cheers, Bruce On Wed, Feb 25, 2015 at 5:06 AM, Karsten Schmidt i...@toxi.co.uk wrote: Hi guys, thi.ng is a collection of over a dozen largely x-platform Clojure Clojurescript libs for computational/generative design data visualization tasks. I just wanted to give a little heads up that this project has recently seen a number of releases and, as a whole, by now is generally quite stable and usable (*is used*) for realworld projects (although most libs remain in constant parallel development to make them more feature complete). I've collated a number of images of projects and links to the most important libs here: http://thi.ng/ Most notably of those: http://thi.ng/geom By far the largest sub-project and backbone for most others: A 2D/3D geometry package w/ comprehensive vector algebra, swizzling, intersections, matrix types helpers, quaternions, pure shape primitives with ~50 protocols for polymorphic enquiry manipulation, meshes (incl. I/O), mesh subdivisions, CSG mesh ops, Verlet physics engine (only particles, springs, behaviors)... Most of this lib is pure geometry w/ no rendering specifics, although there're separate modules for SVG rendering w/ shader support decorators [1], WebGL wrapper and converters from shapes/meshes to VBOs and various shader presets/utils. http://thi.ng/shadergraph GLSL (WebGL) pure function library dependency graph (based on com.stuartsierra/dependency), GLSL minification during CLJS compile time http://thi.ng/color RGB, HSV, CMYK, CSS conversions, color presets (incl. D3 category schemes) http://thi.ng/luxor Complete scene compiler DSL for http://luxrender.net, based around thi.ng/geom http://thi.ng/morphogen Declarative 3D form evolution through tree-based transformations, basically an AST generator of geometric operations to transform a single seed node into complex 3D objects http://thi.ng/tweeny Interpolation of nested (presumably animation related) data structures. Allows tweening of deeply nested maps/vectors with completely flexible tween fns/targets and hence easy definition of complex timelines http://thi.ng/validate Purely functional, composable data validation optional corrections for nested data. Supports both maps vectors, wildcards, comes with many predefined validators, but extensible... http://thi.ng/trio A generic, non-RDF specific triple store API and feature rich SPARQL-like query engine (and my prime example of using the literate programming approach with org-mode[2][3]) Last but not least: Super special thanks are due to the following people: Rich, Alex + rest of clojure.core David (+everyone else involved) for the immense effort on making CLJS proper useful, Chas,
Re: [ClojureScript] [ANN] thi.ng collection update (CLJ/CLJS)
Computational design = using computational approaches to design problems, for anything from analysis, implementation to representation... CSG is indeed only for meshes since it's based on BSP partitioning and because of that also has a few edge cases (due to float precision) where it breaks down and can cause small holes to appear (but these can be fixed with Meshlab/Blender etc). Does OpenSCAD *not* use tessellated geometry for boolean ops? I always was under the impression it does too... need to double check! The other way to do it (and actually easier) is via voxels. There's a really old iso surface implementation in [1], but that needs a complete rewrite and is therefore not bundled with any current releases... Again, I wish there would be more activity in Clojureland underway in these non-web-tech related fields (we have dozens of server dom libs, but not that much for design, modelling, architecture, fabrication). That's not trying to be defensive in any way, but a single person can only do that much and all the features tools provided so far were purely developed on a need to have basis (obviously with a priority to be as re-usable as possible). Hth! K. On 25 February 2015 at 23:21, Jason Felice jason.m.fel...@gmail.com wrote: So... what is computational design? I've been using OpenSCAD to make models for 3D printing, and I keep wishing for a Clojure syntax and real functions and things. Is this it? (It doesn't seem to have constructive solid geometry for things which aren't meshes.) -Jason On Wed, Feb 25, 2015 at 4:13 PM, Karsten Schmidt i...@toxi.co.uk wrote: That's a good point, Bruce! To be honest, I don't know anymore, but it makes complete sense to change it. Consider it done! :) As for your mapping question, yes, of course! I've done a few of them. E.g. the first pic on the website [1] was a project for The ODI in 2013 and is a map of different council/borough stats of London (here knife crime). The shape files were first retrieved processed with the thi.ng/trio lib directly from the UK statistics office's SPARQL endpoint [2], then projected to Mercator, converted to 2d polygons, smoothed them and then extruded as 3D walled meshes and exported as STL files using geom. To create that rendered image, another function then combined all borough meshes into a complete render scene for Luxrender (using the luxor lib). Since this all was for a 60sec animation, I also wrote the tweeny lib for that project to allow me to define the timeline for the various camera, mesh, light shader changes. The whole bundle was then sent to EC2 and rendered on 340+ CPUs... basically, spawned a private render farm. Alternatively with 30 lines of code you could query any UK constituency (or use similar endpoints for other countries), do those initial shape transformations and send the resulting STL mesh file straight to a 3D printer... For online use, of course the SVG or WebGL modules would be more interesting, but these really would just deal with that last transformation/visualization step, i.e. turning a thi.ng.geom.Polygon2 into an SVG polygon node or tesselate it and stuff it into WebGL buffer to display... For more flexible mapping, it'd be great to port some/all of the projections from [3] in its own clj lib for easier (and non-JS related) access... [1] http://thi.ng/img/04.jpg [2] http://statistics.data.gov.uk/doc/statistical-geography [3] https://github.com/d3/d3-geo-projection/ Hth! On 25 February 2015 at 22:34, Bruce Durling b...@otfrom.com wrote: Karsten, Is there a reason why you went with a README.md and then an index.org rather than a plain README.org? (love all the rest of it and loved your use of it at The Barbican. I need to get my head around it all. I'm wondering if I can use it for some of the geographic and other charting things I do a lot of). cheers, Bruce On Wed, Feb 25, 2015 at 5:06 AM, Karsten Schmidt i...@toxi.co.uk wrote: Hi guys, thi.ng is a collection of over a dozen largely x-platform Clojure Clojurescript libs for computational/generative design data visualization tasks. I just wanted to give a little heads up that this project has recently seen a number of releases and, as a whole, by now is generally quite stable and usable (*is used*) for realworld projects (although most libs remain in constant parallel development to make them more feature complete). I've collated a number of images of projects and links to the most important libs here: http://thi.ng/ Most notably of those: http://thi.ng/geom By far the largest sub-project and backbone for most others: A 2D/3D geometry package w/ comprehensive vector algebra, swizzling, intersections, matrix types helpers, quaternions, pure shape primitives with ~50 protocols for polymorphic enquiry manipulation, meshes (incl. I/O), mesh subdivisions, CSG mesh ops, Verlet physics engine (only particles,
Re: [ClojureScript] [ANN] thi.ng collection update (CLJ/CLJS)
I totally thought that map was a photo of 3d printed shapes, but it makes sense that you're using luxrender now. Is there a video of the animation online somewhere? On Wed Feb 25 2015 at 6:13:25 PM Karsten Schmidt i...@toxi.co.uk wrote: That's a good point, Bruce! To be honest, I don't know anymore, but it makes complete sense to change it. Consider it done! :) As for your mapping question, yes, of course! I've done a few of them. E.g. the first pic on the website [1] was a project for The ODI in 2013 and is a map of different council/borough stats of London (here knife crime). The shape files were first retrieved processed with the thi.ng/trio lib directly from the UK statistics office's SPARQL endpoint [2], then projected to Mercator, converted to 2d polygons, smoothed them and then extruded as 3D walled meshes and exported as STL files using geom. To create that rendered image, another function then combined all borough meshes into a complete render scene for Luxrender (using the luxor lib). Since this all was for a 60sec animation, I also wrote the tweeny lib for that project to allow me to define the timeline for the various camera, mesh, light shader changes. The whole bundle was then sent to EC2 and rendered on 340+ CPUs... basically, spawned a private render farm. Alternatively with 30 lines of code you could query any UK constituency (or use similar endpoints for other countries), do those initial shape transformations and send the resulting STL mesh file straight to a 3D printer... For online use, of course the SVG or WebGL modules would be more interesting, but these really would just deal with that last transformation/visualization step, i.e. turning a thi.ng.geom.Polygon2 into an SVG polygon node or tesselate it and stuff it into WebGL buffer to display... For more flexible mapping, it'd be great to port some/all of the projections from [3] in its own clj lib for easier (and non-JS related) access... [1] http://thi.ng/img/04.jpg [2] http://statistics.data.gov.uk/doc/statistical-geography [3] https://github.com/d3/d3-geo-projection/ Hth! On 25 February 2015 at 22:34, Bruce Durling b...@otfrom.com wrote: Karsten, Is there a reason why you went with a README.md and then an index.org rather than a plain README.org? (love all the rest of it and loved your use of it at The Barbican. I need to get my head around it all. I'm wondering if I can use it for some of the geographic and other charting things I do a lot of). cheers, Bruce On Wed, Feb 25, 2015 at 5:06 AM, Karsten Schmidt i...@toxi.co.uk wrote: Hi guys, thi.ng is a collection of over a dozen largely x-platform Clojure Clojurescript libs for computational/generative design data visualization tasks. I just wanted to give a little heads up that this project has recently seen a number of releases and, as a whole, by now is generally quite stable and usable (*is used*) for realworld projects (although most libs remain in constant parallel development to make them more feature complete). I've collated a number of images of projects and links to the most important libs here: http://thi.ng/ Most notably of those: http://thi.ng/geom By far the largest sub-project and backbone for most others: A 2D/3D geometry package w/ comprehensive vector algebra, swizzling, intersections, matrix types helpers, quaternions, pure shape primitives with ~50 protocols for polymorphic enquiry manipulation, meshes (incl. I/O), mesh subdivisions, CSG mesh ops, Verlet physics engine (only particles, springs, behaviors)... Most of this lib is pure geometry w/ no rendering specifics, although there're separate modules for SVG rendering w/ shader support decorators [1], WebGL wrapper and converters from shapes/meshes to VBOs and various shader presets/utils. http://thi.ng/shadergraph GLSL (WebGL) pure function library dependency graph (based on com.stuartsierra/dependency), GLSL minification during CLJS compile time http://thi.ng/color RGB, HSV, CMYK, CSS conversions, color presets (incl. D3 category schemes) http://thi.ng/luxor Complete scene compiler DSL for http://luxrender.net, based around thi.ng/geom http://thi.ng/morphogen Declarative 3D form evolution through tree-based transformations, basically an AST generator of geometric operations to transform a single seed node into complex 3D objects http://thi.ng/tweeny Interpolation of nested (presumably animation related) data structures. Allows tweening of deeply nested maps/vectors with completely flexible tween fns/targets and hence easy definition of complex timelines http://thi.ng/validate Purely functional, composable data validation optional corrections for nested data. Supports both maps vectors, wildcards, comes with many predefined validators, but extensible... http://thi.ng/trio A generic, non-RDF specific triple store
Re: [ClojureScript] [ANN] thi.ng collection update (CLJ/CLJS)
This draft anim was created for The ODI and shows 2 years (summer 2011-2013) worth of London knife crime (based on open data ambulance AE reports): http://media.thi.ng/2013/odi/20131029-heatmap-draft-1280x960.mp4 On 26 February 2015 at 00:42, Dylan Butman dbut...@gmail.com wrote: I totally thought that map was a photo of 3d printed shapes, but it makes sense that you're using luxrender now. Is there a video of the animation online somewhere? On Wed Feb 25 2015 at 6:13:25 PM Karsten Schmidt i...@toxi.co.uk wrote: That's a good point, Bruce! To be honest, I don't know anymore, but it makes complete sense to change it. Consider it done! :) As for your mapping question, yes, of course! I've done a few of them. E.g. the first pic on the website [1] was a project for The ODI in 2013 and is a map of different council/borough stats of London (here knife crime). The shape files were first retrieved processed with the thi.ng/trio lib directly from the UK statistics office's SPARQL endpoint [2], then projected to Mercator, converted to 2d polygons, smoothed them and then extruded as 3D walled meshes and exported as STL files using geom. To create that rendered image, another function then combined all borough meshes into a complete render scene for Luxrender (using the luxor lib). Since this all was for a 60sec animation, I also wrote the tweeny lib for that project to allow me to define the timeline for the various camera, mesh, light shader changes. The whole bundle was then sent to EC2 and rendered on 340+ CPUs... basically, spawned a private render farm. Alternatively with 30 lines of code you could query any UK constituency (or use similar endpoints for other countries), do those initial shape transformations and send the resulting STL mesh file straight to a 3D printer... For online use, of course the SVG or WebGL modules would be more interesting, but these really would just deal with that last transformation/visualization step, i.e. turning a thi.ng.geom.Polygon2 into an SVG polygon node or tesselate it and stuff it into WebGL buffer to display... For more flexible mapping, it'd be great to port some/all of the projections from [3] in its own clj lib for easier (and non-JS related) access... [1] http://thi.ng/img/04.jpg [2] http://statistics.data.gov.uk/doc/statistical-geography [3] https://github.com/d3/d3-geo-projection/ Hth! On 25 February 2015 at 22:34, Bruce Durling b...@otfrom.com wrote: Karsten, Is there a reason why you went with a README.md and then an index.org rather than a plain README.org? (love all the rest of it and loved your use of it at The Barbican. I need to get my head around it all. I'm wondering if I can use it for some of the geographic and other charting things I do a lot of). cheers, Bruce On Wed, Feb 25, 2015 at 5:06 AM, Karsten Schmidt i...@toxi.co.uk wrote: Hi guys, thi.ng is a collection of over a dozen largely x-platform Clojure Clojurescript libs for computational/generative design data visualization tasks. I just wanted to give a little heads up that this project has recently seen a number of releases and, as a whole, by now is generally quite stable and usable (*is used*) for realworld projects (although most libs remain in constant parallel development to make them more feature complete). I've collated a number of images of projects and links to the most important libs here: http://thi.ng/ Most notably of those: http://thi.ng/geom By far the largest sub-project and backbone for most others: A 2D/3D geometry package w/ comprehensive vector algebra, swizzling, intersections, matrix types helpers, quaternions, pure shape primitives with ~50 protocols for polymorphic enquiry manipulation, meshes (incl. I/O), mesh subdivisions, CSG mesh ops, Verlet physics engine (only particles, springs, behaviors)... Most of this lib is pure geometry w/ no rendering specifics, although there're separate modules for SVG rendering w/ shader support decorators [1], WebGL wrapper and converters from shapes/meshes to VBOs and various shader presets/utils. http://thi.ng/shadergraph GLSL (WebGL) pure function library dependency graph (based on com.stuartsierra/dependency), GLSL minification during CLJS compile time http://thi.ng/color RGB, HSV, CMYK, CSS conversions, color presets (incl. D3 category schemes) http://thi.ng/luxor Complete scene compiler DSL for http://luxrender.net, based around thi.ng/geom http://thi.ng/morphogen Declarative 3D form evolution through tree-based transformations, basically an AST generator of geometric operations to transform a single seed node into complex 3D objects http://thi.ng/tweeny Interpolation of nested (presumably animation related) data structures. Allows tweening of deeply nested maps/vectors with completely flexible tween fns/targets and hence easy definition of complex
Re: Is Caribou Dormant ?
Caribou was Clojure's Rails so I'm sad to see it wither. I think Clojure adoption continues to suffer from the lack of a full-featured, strongly-backed web framework like Play and Rails. I don't see why support for a big framework can't co-exist with lightweight library composition options. The Ruby community embraces diversity from Sinatra all the way up to Rails with plenty of variety in between. Different projects developers require different approaches and there are many advantages in using a large, strongly supported web framework. See Aaron Bedra's excellent video - www.youtube.com/watch?v=CBL59w7fXw4 - for more on this. gvim On 25/02/2015 23:36, Geraldo Lopes de Souza wrote: Hi, I'm checking Caribou, and wanna know if anyone is using it. It appears that it is a dormant project by the looks of the last update https://github.com/caribou/caribou Thanks in advance, Geraldo Lopes de Souza -- 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: should edn recognise defrecord?
Thanks miner. I see, so I have to treat each record individually. Never mind - I was only using defrecord so I could dispatch on class and protocols. multi-methods and keywords will suffice here. Thanks again. On Tuesday, 24 February 2015 22:04:55 UTC, miner wrote: The edn format does not include records. The transit README gives an example of how to write a transit handler for a record. See the section on extensibility. https://github.com/cognitect/transit-format#extensibility Before transit existed, there was a little library that I used to encode a Clojure record as a tagged literal (for edn compatibility). It’s only for the Clojure side at the moment, but I imagine it wouldn’t be hard to port to CLJS. However, I suggest that you use transit. https://github.com/miner/tagged On Feb 24, 2015, at 4:40 PM, Colin Yates colin...@gmail.com javascript: wrote: I am sending instances of defrecords from clojurescript via transmit/edn and getting: 2015-Feb-24 19:23:52 + dev-os-mbp.local DEBUG [taoensso.sente] - Bad package: [[:client/message #health.shared.domain.PingCommand{}]] (clojure.lang.ExceptionInfo: No reader function for tag health.shared.domain.PingCommand {:type :reader-exception}) The defrecord is defined using cljx and is definitely there on the server. Do I need to write a reader function to recognise instances of defrecord - my assumption was that this should just work? 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: Why no h2 1.4.176
2015-02-25 10:10 GMT+01:00 Shantanu Kumar kumar.shant...@gmail.com: This has nothing to do with Leiningen, I think. The H2 artifacts are here: http://mvnrepository.com/artifact/com.h2database/h2 You can only use the artifacts that are available, which doesn't include 1.4.176 on Maven Central. In the mvnrepository (the link you gave) there is 1.4.176. (It is used 82 times.) How to get it replicated to Maven Central? On Wednesday, 25 February 2015 14:27:51 UTC+5:30, Cecil Westerhof wrote: I am starting to play with SQL and Clojure. My choice (at least to start with is H2). With Leiningen you can use version 1.4.77 up-to 1.4.185, but those are all beta version. I would prefer to work with the last stable version which is 1.4.176. Why is that not included in central or clojars? -- Cecil Westerhof -- 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: Why no h2 1.4.176
On Wednesday, 25 February 2015 15:11:14 UTC+5:30, Cecil Westerhof wrote: 2015-02-25 10:10 GMT+01:00 Shantanu Kumar kumar.s...@gmail.com javascript:: This has nothing to do with Leiningen, I think. The H2 artifacts are here: http://mvnrepository.com/artifact/com.h2database/h2 You can only use the artifacts that are available, which doesn't include 1.4.176 on Maven Central. In the mvnrepository (the link you gave) there is 1.4.176. (It is used 82 times.) How to get it replicated to Maven Central? One that is used 82 times is 1.3.176, not 1.4.176 -- you can change the version to 1.3.176 in project.clj to use it. Shantanu On Wednesday, 25 February 2015 14:27:51 UTC+5:30, Cecil Westerhof wrote: I am starting to play with SQL and Clojure. My choice (at least to start with is H2). With Leiningen you can use version 1.4.77 up-to 1.4.185, but those are all beta version. I would prefer to work with the last stable version which is 1.4.176. Why is that not included in central or clojars? -- Cecil Westerhof -- 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: Why no h2 1.4.176
2015-02-25 10:43 GMT+01:00 Shantanu Kumar kumar.shant...@gmail.com: On Wednesday, 25 February 2015 15:11:14 UTC+5:30, Cecil Westerhof wrote: 2015-02-25 10:10 GMT+01:00 Shantanu Kumar kumar.s...@gmail.com: This has nothing to do with Leiningen, I think. The H2 artifacts are here: http://mvnrepository.com/artifact/com.h2database/h2 You can only use the artifacts that are available, which doesn't include 1.4.176 on Maven Central. In the mvnrepository (the link you gave) there is 1.4.176. (It is used 82 times.) How to get it replicated to Maven Central? One that is used 82 times is 1.3.176, not 1.4.176 -- you can change the version to 1.3.176 in project.clj to use it. You are right, I did not look correctly. Took 007-yesql which use 1.4.178 and wanted to go the last stable, not noticing that I also had to change the middle number. Thanks. On Wednesday, 25 February 2015 14:27:51 UTC+5:30, Cecil Westerhof wrote: I am starting to play with SQL and Clojure. My choice (at least to start with is H2). With Leiningen you can use version 1.4.77 up-to 1.4.185, but those are all beta version. I would prefer to work with the last stable version which is 1.4.176. Why is that not included in central or clojars? -- Cecil Westerhof -- 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: [ANN] thi.ng collection update (CLJ/CLJS)
Just took a look at your website, Very nice project. In my opinion a prime example that clojure is suitable for large projects. I don't know if anyone ever thought about it. But I guess the geom library would be a good option as a backend for a plotting library (ggplot style). (eg in incanter, gorilla repl ...) Especially since it both works in clojure and clojurescript. greets and keep up the good work Op woensdag 25 februari 2015 06:07:09 UTC+1 schreef Karsten Schmidt: Hi guys, thi.ng is a collection of over a dozen largely x-platform Clojure Clojurescript libs for computational/generative design data visualization tasks. I just wanted to give a little heads up that this project has recently seen a number of releases and, as a whole, by now is generally quite stable and usable (*is used*) for realworld projects (although most libs remain in constant parallel development to make them more feature complete). I've collated a number of images of projects and links to the most important libs here: http://thi.ng/ Most notably of those: http://thi.ng/geom By far the largest sub-project and backbone for most others: A 2D/3D geometry package w/ comprehensive vector algebra, swizzling, intersections, matrix types helpers, quaternions, pure shape primitives with ~50 protocols for polymorphic enquiry manipulation, meshes (incl. I/O), mesh subdivisions, CSG mesh ops, Verlet physics engine (only particles, springs, behaviors)... Most of this lib is pure geometry w/ no rendering specifics, although there're separate modules for SVG rendering w/ shader support decorators [1], WebGL wrapper and converters from shapes/meshes to VBOs and various shader presets/utils. http://thi.ng/shadergraph GLSL (WebGL) pure function library dependency graph (based on com.stuartsierra/dependency), GLSL minification during CLJS compile time http://thi.ng/color RGB, HSV, CMYK, CSS conversions, color presets (incl. D3 category schemes) http://thi.ng/luxor Complete scene compiler DSL for http://luxrender.net, based around thi.ng/geom http://thi.ng/morphogen Declarative 3D form evolution through tree-based transformations, basically an AST generator of geometric operations to transform a single seed node into complex 3D objects http://thi.ng/tweeny Interpolation of nested (presumably animation related) data structures. Allows tweening of deeply nested maps/vectors with completely flexible tween fns/targets and hence easy definition of complex timelines http://thi.ng/validate Purely functional, composable data validation optional corrections for nested data. Supports both maps vectors, wildcards, comes with many predefined validators, but extensible... http://thi.ng/trio A generic, non-RDF specific triple store API and feature rich SPARQL-like query engine (and my prime example of using the literate programming approach with org-mode[2][3]) Last but not least: Super special thanks are due to the following people: Rich, Alex + rest of clojure.core David (+everyone else involved) for the immense effort on making CLJS proper useful, Chas, Kevin and anyone else working on CLJX... none of this would have been possible without these amazing tools! Best, K. Ps. There're a number of other libs in this collection which are in dire need of updating (last touched spring 2013) - these are related to general OpenCL functionality and voxel rendering. Some of the example images on the above site were created with these... [1] https://github.com/thi-ng/geom/blob/master/geom-svg/src/examples.org [2] https://github.com/thi-ng/trio/blob/master/src/query.org [3] http://orgmode.org/ -- Karsten Schmidt http://postspectacular.com | http://thi.ng/ -- 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: Why no h2 1.4.176
This has nothing to do with Leiningen, I think. The H2 artifacts are here: http://mvnrepository.com/artifact/com.h2database/h2 You can only use the artifacts that are available, which doesn't include 1.4.176 on Maven Central. Shantanu On Wednesday, 25 February 2015 14:27:51 UTC+5:30, Cecil Westerhof wrote: I am starting to play with SQL and Clojure. My choice (at least to start with is H2). With Leiningen you can use version 1.4.77 up-to 1.4.185, but those are all beta version. I would prefer to work with the last stable version which is 1.4.176. Why is that not included in central or clojars? -- Cecil Westerhof -- 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.
Why no h2 1.4.176
I am starting to play with SQL and Clojure. My choice (at least to start with is H2). With Leiningen you can use version 1.4.77 up-to 1.4.185, but those are all beta version. I would prefer to work with the last stable version which is 1.4.176. Why is that not included in central or clojars? -- Cecil Westerhof -- 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.
defmethod inside of a (stuart sierra) component?
Hi, I have a number of commands flying around which need to be handled. defmulti/defmethod seem a nice answer. The problem is that each command handler will need different collaborators (those with long memories will realise this isn't new ground here ;)). I want to do something like: (ns one) (defmulti handle first) (ns two) (defrecord CommandAHandler [collab-1 collab-2] component/Lifecycle (start [this] (defmethod handle :command-a (collab-1 ...))) I realise that the lifecycle of defmethod doesn't match the component (i.e. stopping can't unregister the defmethod), but my main reservation is that a nested defmethod feels a bit weird. Has anyone done anything like this before? 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.