improving as-> macro by adding destructuring support
The as-> macro doesn't work with destructuring. This is invalid code: (-> [1 2] (as-> [a & b] [a (inc b)] [(inc a) b])) Because it is expanded to: (let [[a & b] [1 2] [a & b] [a (inc b)] [a & b] [(inc a) b]] [a & b]) ;; this last expression will not compile But with a little redefinition is possible to make as-> work with destructuring: (defmacro as-> "Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form." {:added "1.5"} [expr name & forms] `(let [~name ~expr ~@(interleave (repeat name) (butlast forms))] ~(last forms))) Now the previous example will expand to: (let [[a & b] [1 2] [a & b] [a (inc b)]] [(inc a) b]) The following example shows why an as-> destructuring compatible macro can be useful. This code parses a defmulti like parameter list by reusing a destructuring form: (defmacro defmulti2 [mm-name & opts] (-> [{} opts] (as-> [m [e & r :as o]] (if (string? e) [(assoc m :docstring e) r] [m o]) (if (map? e) [(assoc m :attr-map e :dispatch-fn (first r)) (next r)] [(assoc m :dispatch-fn e) r]) ... Compare with the original defmulti: (defmacro defmulti [mm-name & options] (let [docstring (if (string? (first options)) (first options) nil) options (if (string? (first options)) (next options) options) m (if (map? (first options)) (first options) {}) options (if (map? (first options)) (next options) options) dispatch-fn (first options) options (next options) m (if docstring (assoc m :doc docstring) m) ... I added a JIRA issue to report & track this (I think) enhacement: http://dev.clojure.org/jira/browse/CLJ-1418 Saludos, Nahuel Greco. -- 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.
deftest and var's metadata
This works ok at the REPL: (def ^{:k :v} a 4) (:k (meta (resolve 'a))) ;=> evaluates to :v, ok. But the same didn't worked inside a clojure.test/deftest: (deftest mytest (def ^{:k :v} b 4) (is (= (resolve 'b) nil)) ;; passed, var is resolved ok (is (= (:k (meta (resolve 'b))) :v))) ;; fails, metadata is nil I know deftest wraps his body in a fn, but this works ok: ((fn [] (def ^{:k :v} c 4) (:k (meta (resolve 'c))) )) Why the deftest case is not working? Saludos, Nahuel Greco. -- 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: deftest and var's metadata
ok, just for the record, I fixed it. Instead of (resolve 'a) you must use (ns-resolve 'test-namespace 'a), because lein test runs the tests in namespace 'userinstead of the one that defined the test (as I wrongly assumed). Also the first test for the existence of the var is wrong, I assumed resolve will raise an exception if not found, but it returns nil. Moral: sleep deprivation is bad for debugging :) Saludos, Nahuel Greco. On Mon, May 26, 2014 at 5:05 AM, Nahuel Greco wrote: > This works ok at the REPL: > > (def ^{:k :v} a 4) > (:k (meta (resolve 'a))) > ;=> evaluates to :v, ok. > > But the same didn't worked inside a clojure.test/deftest: > > (deftest mytest > (def ^{:k :v} b 4) > (is (= (resolve 'b) nil)) ;; passed, var is resolved ok > (is (= (:k (meta (resolve 'b))) :v))) ;; fails, metadata is nil > > I know deftest wraps his body in a fn, but this works ok: > > ((fn [] > (def ^{:k :v} c 4) > (:k (meta (resolve 'c))) > )) > > Why the deftest case is not working? > > > Saludos, > Nahuel Greco. > -- 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: Is there any Clojure magic for "registering" new implementations of something?
why not multimethods? Saludos, Nahuel Greco. On Fri, Aug 22, 2014 at 1:30 PM, Laurens Van Houtven <_...@lvh.cc> wrote: > Hi Clojurers, > > > I'm writing a capability system with Clojure. Make a request to a URL, it > grabs the "plan" for what it should do from the database. A plan consists > (eventually) of atomic "steps". Typical example of a step would be "make an > HTTP request", represented by a map like {:type :http :url " > http://www.example.test"; :method "GET"}. > > I would like to allow people to implement different types of steps (http, > delays, e-mail, ftp...), ideally by modifying as little existing code as > possible. Step implementations have two parts: > > - a step handler (better name suggestions welcome...): a function that > takes a step map of the appropriate type, producing a channel that will > eventually have a result posted on it and be closed > - a step schema (a prismatic/schema schema), describing the step map. > > Right now I manage both of these manually. That works fine, because the > only thing I've implemented so far is HTTP requests ;-) > > I briefly considered protocols for this; perhaps a protocol with a handler > fn and the schema, but AFAIK protocols only know about their extenders, not > so much about their implementations. (Even with manual registration, a > protocol may still be an appropriate tool.) Plus, that wouldn't solve the > problem of dispatching based on type (i.e., given a map like the example > above, find the handler function that can do something with it). > > This project is in its earliest stages, so I am very eager to hear about > wildly different suggestions as well :) > > > thanks in advance > lvh > > -- > 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: Is there any Clojure magic for "registering" new implementations of something?
what about: (defmulti step-handler :type) (defmulti get-schema :type) ;; returns the schema And make your users implement both? Remember schemas are first-class values. Saludos, Nahuel Greco. On Sat, Aug 23, 2014 at 8:08 AM, Laurens Van Houtven <_...@lvh.io> wrote: > Hi Nahuel, > > > Thanks for your suggestion :) > > On 22 Aug 2014, at 19:31, Nahuel Greco wrote: > > > why not multi methods? > > Multimethods definitely solve the registering a handler problem (because > what I really want there is arbitrary dispatch), but don’t solve the “there > must be two of these” problem. I guess I could write a macro for that, but > I don’t know what the macro would have to have to register the > prismatic/schema. I guess I’ll go digging to see if there’s anything in > prismatic/schema that takes a multi-method, and still produces useful > schema validation errors :) > > cheers > lvh > > -- 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: Is there any Clojure magic for "registering" new implementations of something?
Instead of defining Step superschema can you simply do: (s/validate something (get-schema step)) ?? If you need more than that, for example, if you need a named schema to use it in function signatures, then I think you have two options: 1- Define a superschema just like in your example, but using the multimethod instead of a literal: (defmulti get-schema :type) (defmethod get-schema :http [v] {:url s/Str}) (defmethod get-schema :delay [v] {:seconds s/Int}) (def Step (apply s/conditional (flatten (for [type (keys (methods get-schema))] [#(= (:type %) type) (get-schema {:type type})] The problem here is you need to have all the methods already defined by your api users at the moment of defining the Step "superschema". 2- Generalize the problem, you need to define an Schema that resolves dinamically to another based on the value. s/conditional does something like that but is not sufficient. I think is an uncovered corner case in Prismatic Schema, you can try doing something like this: (defrecord SchemaResolver [resolve-fun] s/Schema (walker [this] (fn [value] (s/walker (resolve-fun value (explain [this] ;; not implemented )) (defmulti get-schema :type) (def Step (SchemaResolver. get-schema)) ;; defmethods can be next, ;; because the schema will be resolved dinamically on each ;; validation. (defmethod get-schema :http [v] {:url s/Str}) (defmethod get-schema :delay [v] {:seconds s/Int}) But this will not work because Prismatic Schema does some tricks with dynamic binding when calling walker, so you can't simply delegate this way. Maybe you need to discuss this in the ticket. Saludos, Nahuel Greco. On Mon, Aug 25, 2014 at 7:41 AM, Laurens Van Houtven <_...@lvh.cc> wrote: > Hi Nahuel, > > > On Saturday, August 23, 2014 7:23:42 PM UTC+2, nahuel wrote: >> >> what about: >> >> (defmulti step-handler :type) >> (defmulti get-schema :type) ;; returns the schema >> >> And make your users implement both? Remember schemas are first-class >> values. >> > > The difficulty I'm having is figuring out how to then embed these schemas > into another schema. (The reason I want *that* is because these steps are > composed into different schemas, and I'd like to check the superschema.) > Ideally I would end up with something like: > > (def Step > (s/conditional >#(= (:type %) :http) {:the :http :schema :here} >#(= (:type %) :delay) {:the :delay :schema: :here})) > > ... except with the keys and schemas coming out of the multimethod (or > whatever) instead of being a literal :) > > I guess I could do that with some extended macrology hackery for now; if > my defstep macro stashes all of the schemas in a ref somewhere, I can then > expand to the above code example :) > > I've created a ticket for this on prismatic/schema: > https://github.com/Prismatic/schema/issues/140 > > thanks again, > lvh > > -- > 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: Is there any Clojure magic for "registering" new implementations of something?
PD: Let's continue this thread on the github ticket. Saludos, Nahuel Greco. On Mon, Aug 25, 2014 at 6:51 PM, Nahuel Greco wrote: > Instead of defining Step superschema can you simply do: > > (s/validate something (get-schema step)) > > ?? > > If you need more than that, for example, if you need a named schema to use > it in function signatures, then I think you have two options: > > 1- Define a superschema just like in your example, but using the > multimethod instead of a literal: > > (defmulti get-schema :type) > (defmethod get-schema :http [v] {:url s/Str}) > (defmethod get-schema :delay [v] {:seconds s/Int}) > > (def Step >(apply s/conditional > (flatten (for [type (keys (methods get-schema))] > [#(= (:type %) type) > (get-schema {:type type})] > > The problem here is you need to have all the methods already defined by > your api users at the moment of defining the Step "superschema". > > 2- Generalize the problem, you need to define an Schema that resolves > dinamically to another based on the value. s/conditional does something > like that but is not sufficient. I think is an uncovered corner case in > Prismatic Schema, you can try doing something like this: > > (defrecord SchemaResolver [resolve-fun] > s/Schema > (walker [this] > (fn [value] (s/walker (resolve-fun value > (explain [this] > ;; not implemented > )) > > (defmulti get-schema :type) > > (def Step (SchemaResolver. get-schema)) > > ;; defmethods can be next, > ;; because the schema will be resolved dinamically on each > ;; validation. > (defmethod get-schema :http [v] {:url s/Str}) > (defmethod get-schema :delay [v] {:seconds s/Int}) > > But this will not work because Prismatic Schema does some tricks with > dynamic binding when calling walker, so you can't simply delegate this way. > Maybe you need to discuss this in the ticket. > > > > Saludos, > Nahuel Greco. > > > On Mon, Aug 25, 2014 at 7:41 AM, Laurens Van Houtven <_...@lvh.cc> wrote: > >> Hi Nahuel, >> >> >> On Saturday, August 23, 2014 7:23:42 PM UTC+2, nahuel wrote: >>> >>> what about: >>> >>> (defmulti step-handler :type) >>> (defmulti get-schema :type) ;; returns the schema >>> >>> And make your users implement both? Remember schemas are first-class >>> values. >>> >> >> The difficulty I'm having is figuring out how to then embed these schemas >> into another schema. (The reason I want *that* is because these steps are >> composed into different schemas, and I'd like to check the superschema.) >> Ideally I would end up with something like: >> >> (def Step >> (s/conditional >>#(= (:type %) :http) {:the :http :schema :here} >>#(= (:type %) :delay) {:the :delay :schema: :here})) >> >> ... except with the keys and schemas coming out of the multimethod (or >> whatever) instead of being a literal :) >> >> I guess I could do that with some extended macrology hackery for now; if >> my defstep macro stashes all of the schemas in a ref somewhere, I can then >> expand to the above code example :) >> >> I've created a ticket for this on prismatic/schema: >> https://github.com/Prismatic/schema/issues/140 >> >> thanks again, >> lvh >> >> -- >> 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.
core.async: peek the next value from a channel without consuming it
Currently if you block/park on a channel reading it by using 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: behavior of as-> macro
I reported this issue to the Clojure JIRA a while ago: http://dev.clojure.org/jira/browse/CLJ-1418 , please vote it up. El 29/09/2014 05:55, "Sunil S Nandihalli" escribió: > I think the definition of as-> should be changed to this. I feel this > behavior is more consistent with the rest of clojure. > > (defmacro as-> [expr name & forms] `(let [~name ~expr ~@(interleave > (repeat name) (take (dec (count forms)) forms))] ~(last forms)) > > Thanks, > Sunil > > On Mon, Sep 29, 2014 at 2:11 PM, Sunil S Nandihalli < > sunil.nandiha...@gmail.com> wrote: > >> Hi everybody, >> I get the following when I try to use the as-> macro >> >> >> user=> (def x (as-> {:a 10 :b 20} {:keys [a b] :as w} {:a (* 2 a) :b (* >> 2 b)})) >> #'user/x >> user=> x >> {:keys [20 40], :as {:a 20, :b 40}} >> user=> >> >> I would have expected x to be {:a 20 :b 40}, not what I see above. >> >> Can somebody explain? >> Thanks, >> Sunil. >> > > -- > 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: core.async: peek the next value from a channel without consuming it
I was thinking in a single-consumer scenario with a buffered chan, in which you want to check if you can consume the value before effectively consuming it. As you said, a peek operation has no sense if the channel has multiple consumers. Saludos, Nahuel Greco. On Sat, Oct 4, 2014 at 9:17 PM, Leon Grapenthin wrote: > Why would you want this? To leave the value inside the channel for other > consumers? > > In that case there would be no guarantee that the value returned by the > peek operation is the next value in the channel, because it might have been > consumed already. > > > Best regards, Leon > > > On Monday, September 29, 2014 12:12:33 PM UTC+2, Nahuel Greco wrote: >> >> Currently if you block/park on a channel reading it by using > alts!/alts!! the value will be consumed when it appears, so there is no way >> to block/park waiting a new value without removing it from the channel. >> There is a non-consuming peek operation planned in the core.async roadmap >> or a design rationale exists for not including that operation? >> >> Saludos, >> Nahuel Greco. >> > -- > 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: core.async: peek the next value from a channel without consuming it
Picture the following: producer ---> go-loop ---> external service 1- The producer puts a value to a unbuffered (chan) by doing (>! c v) 2- The go-loop consumes the value with a take operation, **unblocking** the producer 3- The go-loop contacts the external-service but the external service answers it can't process the value yet 4- The go-loop waits some timeout to retry the request to the external service After step 2 the producer continues to compute (suppose an expensive computing) a new value but the previous one wasn't effectively consumed by the external service. I don't want that, I want to enforce an end-to-end flow-control setup where the producer blocks on (>! c v) (the step 1) until the value is consumed by all parties, Sure, this flow control can be solved adding an ack channel and sending an ack from the go-loop to the producer when the external service effectively consumes the value, previously blocking the producer after step 1 waiting that ack. But I think a peek operation in step 2 will be more elegant. Also, I was curious if the implementation of core.async channels limits in some way adding a peek operation. A take-if with a pure predicate can't solve this, because you need to contact the external service to decide to consume the value or not. Saludos, Nahuel Greco. On Sun, Oct 5, 2014 at 9:52 AM, Fluid Dynamics wrote: > On Sunday, October 5, 2014 12:51:04 AM UTC-4, Nahuel Greco wrote: >> >> I was thinking in a single-consumer scenario with a buffered chan, in >> which you want to check if you can consume the value before effectively >> consuming it. As you said, a peek operation has no sense if the channel has >> multiple consumers. >> > > And if you can't consume the value, then what? Nothing ever does, and that > channel becomes useless? > > Actually the only "peek" operation that to me makes much sense would be a > (take-if pred chan) or something similar, which atomically tests the next > value with pred and consumes it or not, so, it can't be consumed elsewhere > between the pred test and optional consumption here. And if not consumed, > two behaviors both occur to me as possible -- return nil or some other > sentinel value for "do not want" or block until the unwanted object is > consumed by someone else and then test the next item, etc.; at which point > you've got four versions of take-if you'd want, the inside-go and > outside-go versions cross product with the two when-not-wanted behaviors. > > At that point, you'd probably be better off just writing a consumer that > splits off the pred-matching items into one out channel and feeds > everything else into a second channel, with your original consumer taking > from the first of these and the others taking from the second. That gets > you the block until version of the behavior. The other version can be had > by making the pred-using consumer the sole consumer of the in channel, > which takes a value, applies pred, and branches, on the "want" branch doing > whatever and on the "do not want" branch putting the value onto an out > channel that feeds the other consumers before taking its own "do not want" > actions. > > -- > 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: core.async: peek the next value from a channel without consuming it
Adrian: I don't see how a pub can help here, in the previous example to consume or not the value was decided not on some property intrinsic to the value (one you can create a topic from), but on the result of sending it to an external service. Saludos, Nahuel Greco. On Sun, Oct 5, 2014 at 12:59 PM, wrote: > I think you can achieve an effect similar to what you want by using a pub > with an appropriate topic function that classifies the input in some way, > and then subscribing to the topic whose value you want to see. This also > has the benefit of automatically 'mult'ing the channel input, so you can > have multiple consumers looking for the same value. > > On Sunday, October 5, 2014 11:33:16 AM UTC-4, Nahuel Greco wrote: >> >> Picture the following: >> >> producer ---> go-loop ---> external service >> >> 1- The producer puts a value to a unbuffered (chan) by doing (>! c v) >> 2- The go-loop consumes the value with a take operation, **unblocking** >> the producer >> 3- The go-loop contacts the external-service but the external service >> answers it can't process the value yet >> 4- The go-loop waits some timeout to retry the request to the external >> service >> >> After step 2 the producer continues to compute (suppose an expensive >> computing) a new value but the previous one wasn't effectively consumed by >> the external service. >> I don't want that, I want to enforce an end-to-end flow-control setup >> where the producer blocks on (>! c v) (the step 1) until the value is >> consumed by all parties, >> >> Sure, this flow control can be solved adding an ack channel and sending >> an ack from the go-loop to the producer when the external service >> effectively consumes the value, previously blocking the producer after step >> 1 waiting that ack. >> But I think a peek operation in step 2 will be more elegant. Also, I was >> curious if the implementation of core.async channels limits in some way >> adding a peek operation. >> >> A take-if with a pure predicate can't solve this, because you need to >> contact the external service to decide to consume the value or not. >> >> >> Saludos, >> Nahuel Greco. >> >> On Sun, Oct 5, 2014 at 9:52 AM, Fluid Dynamics wrote: >> >>> On Sunday, October 5, 2014 12:51:04 AM UTC-4, Nahuel Greco wrote: >>>> >>>> I was thinking in a single-consumer scenario with a buffered chan, in >>>> which you want to check if you can consume the value before effectively >>>> consuming it. As you said, a peek operation has no sense if the channel has >>>> multiple consumers. >>>> >>> >>> And if you can't consume the value, then what? Nothing ever does, and >>> that channel becomes useless? >>> >>> Actually the only "peek" operation that to me makes much sense would be >>> a (take-if pred chan) or something similar, which atomically tests the next >>> value with pred and consumes it or not, so, it can't be consumed elsewhere >>> between the pred test and optional consumption here. And if not consumed, >>> two behaviors both occur to me as possible -- return nil or some other >>> sentinel value for "do not want" or block until the unwanted object is >>> consumed by someone else and then test the next item, etc.; at which point >>> you've got four versions of take-if you'd want, the inside-go and >>> outside-go versions cross product with the two when-not-wanted behaviors. >>> >>> At that point, you'd probably be better off just writing a consumer that >>> splits off the pred-matching items into one out channel and feeds >>> everything else into a second channel, with your original consumer taking >>> from the first of these and the others taking from the second. That gets >>> you the block until version of the behavior. The other version can be had >>> by making the pred-using consumer the sole consumer of the in channel, >>> which takes a value, applies pred, and branches, on the "want" branch doing >>> whatever and on the "do not want" branch putting the value onto an out >>> channel that feeds the other consumers before taking its own "do not want" >>> actions. >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clo...@googlegroups.com >>> Note that posts from new membe
Re: core.async: peek the next value from a channel without consuming it
previous example with the peek operation: 1- The producer puts a value to a unbuffered (chan) by doing (>! c v) 2- The go-loop unparks from (peek wrote: > Then how would peeking at the value help? > > On Sunday, October 5, 2014 12:14:32 PM UTC-4, Nahuel Greco wrote: >> >> Adrian: I don't see how a pub can help here, in the previous example to >> consume or not the value was decided not on some property intrinsic to the >> value (one you can create a topic from), but on the result of sending it to >> an external service. >> >> >> Saludos, >> Nahuel Greco. >> >> On Sun, Oct 5, 2014 at 12:59 PM, wrote: >> >>> I think you can achieve an effect similar to what you want by using a >>> pub with an appropriate topic function that classifies the input in some >>> way, and then subscribing to the topic whose value you want to see. This >>> also has the benefit of automatically 'mult'ing the channel input, so you >>> can have multiple consumers looking for the same value. >>> >>> On Sunday, October 5, 2014 11:33:16 AM UTC-4, Nahuel Greco wrote: >>>> >>>> Picture the following: >>>> >>>> producer ---> go-loop ---> external service >>>> >>>> 1- The producer puts a value to a unbuffered (chan) by doing (>! c v) >>>> 2- The go-loop consumes the value with a take operation, **unblocking** >>>> the producer >>>> 3- The go-loop contacts the external-service but the external service >>>> answers it can't process the value yet >>>> 4- The go-loop waits some timeout to retry the request to the external >>>> service >>>> >>>> After step 2 the producer continues to compute (suppose an expensive >>>> computing) a new value but the previous one wasn't effectively consumed by >>>> the external service. >>>> I don't want that, I want to enforce an end-to-end flow-control setup >>>> where the producer blocks on (>! c v) (the step 1) until the value is >>>> consumed by all parties, >>>> >>>> Sure, this flow control can be solved adding an ack channel and sending >>>> an ack from the go-loop to the producer when the external service >>>> effectively consumes the value, previously blocking the producer after step >>>> 1 waiting that ack. >>>> But I think a peek operation in step 2 will be more elegant. Also, I >>>> was curious if the implementation of core.async channels limits in some way >>>> adding a peek operation. >>>> >>>> A take-if with a pure predicate can't solve this, because you need to >>>> contact the external service to decide to consume the value or not. >>>> >>>> >>>> Saludos, >>>> Nahuel Greco. >>>> >>>> On Sun, Oct 5, 2014 at 9:52 AM, Fluid Dynamics >>>> wrote: >>>> >>>>> On Sunday, October 5, 2014 12:51:04 AM UTC-4, Nahuel Greco wrote: >>>>>> >>>>>> I was thinking in a single-consumer scenario with a buffered chan, in >>>>>> which you want to check if you can consume the value before effectively >>>>>> consuming it. As you said, a peek operation has no sense if the channel >>>>>> has >>>>>> multiple consumers. >>>>>> >>>>> >>>>> And if you can't consume the value, then what? Nothing ever does, and >>>>> that channel becomes useless? >>>>> >>>>> Actually the only "peek" operation that to me makes much sense would >>>>> be a (take-if pred chan) or something similar, which atomically tests the >>>>> next value with pred and consumes it or not, so, it can't be consumed >>>>> elsewhere between the pred test and optional consumption here. And if not >>>>> consumed, two behaviors both occur to me as possible -- return nil or some >>>>> other sentinel value for "do not want" or block until the unwanted object >>>>> is consumed by someone else and then test the next item, etc.; at which >>>>> point you've got four versions of take-if you'd want, the inside-go and >>>>> outside-go versions cross product with the two when-not-wanted behaviors. >>>>> >>>>> At that point, you'd probably be better off just writing a consumer >>>>> that splits off the pred-matching item
Re: core.async: peek the next value from a channel without consuming it
You can do that without a pub, the producer can send a new (chan) inside the request to the go-loop and the go-loop will ack on that chan when getting a good response from the external service. That schema solves this scenario, I mentioned it in the previous mail, but I think a peek operation maybe could be better and can simplify the producer code. Saludos, Nahuel Greco. On Sun, Oct 5, 2014 at 1:57 PM, wrote: > Ah, I think we're on the same page now. I've come across the need for this > recently in some code for a UDP based protocol between a multiplayer game > client and server. > > I still think a pub fits in here nicely. You can consume the value from > the channel in question and park until you get an acknowledgment from the > external service (or timeout). The producer would subscribe to another > topic on your pub that will get a value put onto it when acknowledgment or > time out occurs in the consumer. Be sure to close the subs after you've > gotten the ack or timed out. > > On Sunday, October 5, 2014 12:40:25 PM UTC-4, Nahuel Greco wrote: >> >> previous example with the peek operation: >> >> 1- The producer puts a value to a unbuffered (chan) by doing (>! c v) >> 2- The go-loop unparks from (peek> producer keeps parked >> 3- The go-loop contacts the external-service >> 4-A If the external-service answer is ok, the go-loop consume (and >> discard) the value by doing a normal (> 4-B If the external-service answers it cannot process the value, the >> go-loop waits until a timeout to retry step 3 >> >> The producer only unparks when the value is effectively consumed by the >> external service. That's my objective. >> >> I think your pub proposal replaces the take-if proposal given before, but >> I think take-if (and pub) doesn't work for this scenario. >> >> >> Saludos, >> Nahuel Greco. >> >> On Sun, Oct 5, 2014 at 1:20 PM, wrote: >> >>> Then how would peeking at the value help? >>> >>> On Sunday, October 5, 2014 12:14:32 PM UTC-4, Nahuel Greco wrote: >>>> >>>> Adrian: I don't see how a pub can help here, in the previous example to >>>> consume or not the value was decided not on some property intrinsic to the >>>> value (one you can create a topic from), but on the result of sending it to >>>> an external service. >>>> >>>> >>>> Saludos, >>>> Nahuel Greco. >>>> >>>> On Sun, Oct 5, 2014 at 12:59 PM, wrote: >>>> >>>>> I think you can achieve an effect similar to what you want by using a >>>>> pub with an appropriate topic function that classifies the input in some >>>>> way, and then subscribing to the topic whose value you want to see. This >>>>> also has the benefit of automatically 'mult'ing the channel input, so you >>>>> can have multiple consumers looking for the same value. >>>>> >>>>> On Sunday, October 5, 2014 11:33:16 AM UTC-4, Nahuel Greco wrote: >>>>>> >>>>>> Picture the following: >>>>>> >>>>>> producer ---> go-loop ---> external service >>>>>> >>>>>> 1- The producer puts a value to a unbuffered (chan) by doing (>! c v) >>>>>> 2- The go-loop consumes the value with a take operation, >>>>>> **unblocking** the producer >>>>>> 3- The go-loop contacts the external-service but the external service >>>>>> answers it can't process the value yet >>>>>> 4- The go-loop waits some timeout to retry the request to the >>>>>> external service >>>>>> >>>>>> After step 2 the producer continues to compute (suppose an expensive >>>>>> computing) a new value but the previous one wasn't effectively consumed >>>>>> by >>>>>> the external service. >>>>>> I don't want that, I want to enforce an end-to-end flow-control setup >>>>>> where the producer blocks on (>! c v) (the step 1) until the value is >>>>>> consumed by all parties, >>>>>> >>>>>> Sure, this flow control can be solved adding an ack channel and >>>>>> sending an ack from the go-loop to the producer when the external service >>>>>> effectively consumes the value, previously blocking the producer after >>>>>> step >>>>>> 1 waiting that ack. >>>
Re: core.async: peek the next value from a channel without consuming it
Maybe not, maybe you want to reserve the cpu cycles for other tasks, or the producer needs a confirmation for other purposes before computing or requesting the value from another party. This is a simplified and distilled scenario. El 05/10/2014 16:55, "Leon Grapenthin" escribió: > > > On Sunday, October 5, 2014 5:33:16 PM UTC+2, Nahuel Greco wrote: >> >> Picture the following: >> >> producer ---> go-loop ---> external service >> >> 1- The producer puts a value to a unbuffered (chan) by doing (>! c v) >> 2- The go-loop consumes the value with a take operation, **unblocking** >> the producer >> 3- The go-loop contacts the external-service but the external service >> answers it can't process the value yet >> 4- The go-loop waits some timeout to retry the request to the external >> service >> >> After step 2 the producer continues to compute (suppose an expensive >> computing) a new value but the previous one wasn't effectively consumed by >> the external service. >> I don't want that, I want to enforce an end-to-end flow-control setup >> where the producer blocks on (>! c v) (the step 1) until the value is >> consumed by all parties, >> > > If producing the next value is expensive, why would you want to delay it > from point 2 to after point 4? Once the external service has processed the > current value, you want the next value available as soon as possible, > wouldn't you? > > >> Sure, this flow control can be solved adding an ack channel and sending >> an ack from the go-loop to the producer when the external service >> effectively consumes the value, previously blocking the producer after step >> 1 waiting that ack. >> But I think a peek operation in step 2 will be more elegant. Also, I was >> curious if the implementation of core.async channels limits in some way >> adding a peek operation. >> >> A take-if with a pure predicate can't solve this, because you need to >> contact the external service to decide to consume the value or not. >> >> >> Saludos, >> Nahuel Greco. >> >> On Sun, Oct 5, 2014 at 9:52 AM, Fluid Dynamics wrote: >> >>> On Sunday, October 5, 2014 12:51:04 AM UTC-4, Nahuel Greco wrote: >>>> >>>> I was thinking in a single-consumer scenario with a buffered chan, in >>>> which you want to check if you can consume the value before effectively >>>> consuming it. As you said, a peek operation has no sense if the channel has >>>> multiple consumers. >>>> >>> >>> And if you can't consume the value, then what? Nothing ever does, and >>> that channel becomes useless? >>> >>> Actually the only "peek" operation that to me makes much sense would be >>> a (take-if pred chan) or something similar, which atomically tests the next >>> value with pred and consumes it or not, so, it can't be consumed elsewhere >>> between the pred test and optional consumption here. And if not consumed, >>> two behaviors both occur to me as possible -- return nil or some other >>> sentinel value for "do not want" or block until the unwanted object is >>> consumed by someone else and then test the next item, etc.; at which point >>> you've got four versions of take-if you'd want, the inside-go and >>> outside-go versions cross product with the two when-not-wanted behaviors. >>> >>> At that point, you'd probably be better off just writing a consumer that >>> splits off the pred-matching items into one out channel and feeds >>> everything else into a second channel, with your original consumer taking >>> from the first of these and the others taking from the second. That gets >>> you the block until version of the behavior. The other version can be had >>> by making the pred-using consumer the sole consumer of the in channel, >>> which takes a value, applies pred, and branches, on the "want" branch doing >>> whatever and on the "do not want" branch putting the value onto an out >>> channel that feeds the other consumers before taking its own "do not want" >>> actions. >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clo...@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email
Re: core.async: peek the next value from a channel without consuming it
No reservation, the ack solution works, but 1- I think the producer code can be simplified with the peek operation and 2- I want to know is there is a fudamental limitation in chans design/implementation prohibiting adding a peek operation. El 05/10/2014 17:03, "Gary Verhaegen" escribió: > I think you should go for the ack solution. What is your reservation about > it? > > On Sunday, 5 October 2014, Leon Grapenthin > wrote: > >> >> >> On Sunday, October 5, 2014 5:33:16 PM UTC+2, Nahuel Greco wrote: >>> >>> Picture the following: >>> >>> producer ---> go-loop ---> external service >>> >>> 1- The producer puts a value to a unbuffered (chan) by doing (>! c v) >>> 2- The go-loop consumes the value with a take operation, **unblocking** >>> the producer >>> 3- The go-loop contacts the external-service but the external service >>> answers it can't process the value yet >>> 4- The go-loop waits some timeout to retry the request to the external >>> service >>> >>> After step 2 the producer continues to compute (suppose an expensive >>> computing) a new value but the previous one wasn't effectively consumed by >>> the external service. >>> I don't want that, I want to enforce an end-to-end flow-control setup >>> where the producer blocks on (>! c v) (the step 1) until the value is >>> consumed by all parties, >>> >> >> If producing the next value is expensive, why would you want to delay it >> from point 2 to after point 4? Once the external service has processed the >> current value, you want the next value available as soon as possible, >> wouldn't you? >> >> >>> Sure, this flow control can be solved adding an ack channel and sending >>> an ack from the go-loop to the producer when the external service >>> effectively consumes the value, previously blocking the producer after step >>> 1 waiting that ack. >>> But I think a peek operation in step 2 will be more elegant. Also, I was >>> curious if the implementation of core.async channels limits in some way >>> adding a peek operation. >>> >>> A take-if with a pure predicate can't solve this, because you need to >>> contact the external service to decide to consume the value or not. >>> >>> >>> Saludos, >>> Nahuel Greco. >>> >>> On Sun, Oct 5, 2014 at 9:52 AM, Fluid Dynamics >>> wrote: >>> >>>> On Sunday, October 5, 2014 12:51:04 AM UTC-4, Nahuel Greco wrote: >>>>> >>>>> I was thinking in a single-consumer scenario with a buffered chan, in >>>>> which you want to check if you can consume the value before effectively >>>>> consuming it. As you said, a peek operation has no sense if the channel >>>>> has >>>>> multiple consumers. >>>>> >>>> >>>> And if you can't consume the value, then what? Nothing ever does, and >>>> that channel becomes useless? >>>> >>>> Actually the only "peek" operation that to me makes much sense would be >>>> a (take-if pred chan) or something similar, which atomically tests the next >>>> value with pred and consumes it or not, so, it can't be consumed elsewhere >>>> between the pred test and optional consumption here. And if not consumed, >>>> two behaviors both occur to me as possible -- return nil or some other >>>> sentinel value for "do not want" or block until the unwanted object is >>>> consumed by someone else and then test the next item, etc.; at which point >>>> you've got four versions of take-if you'd want, the inside-go and >>>> outside-go versions cross product with the two when-not-wanted behaviors. >>>> >>>> At that point, you'd probably be better off just writing a consumer >>>> that splits off the pred-matching items into one out channel and feeds >>>> everything else into a second channel, with your original consumer taking >>>> from the first of these and the others taking from the second. That gets >>>> you the block until version of the behavior. The other version can be had >>>> by making the pred-using consumer the sole consumer of the in channel, >>>> which takes a value, applies pred, and branches, on the "want" branch doing >>>> whatever and on the "do not want" branch putting the value onto an out >>>>
Re: core.async: peek the next value from a channel without consuming it
Fluid: as you said, backpressure on the outgoing channel will be sufficient to avoid producer to overrun consumer (without using any extra ack-channel), but the producer will compute a new not-yet-used value before blocking on sending it to consumer. That's what I want to avoid. I can also use alts! on the producer to check if he can write to the channel before computing the value, but I wanted to keep the code in the producer in the simplest form possible (a simple (>! c v) parking until all parties consume the value, avoiding an ack-chan or an alts!) . Eduard: Exactly. Fregal: If middleman is managing all the communication with the external service for *multiple* producers, then it can't be reduced to a simple synchronous function call from a producer, hence the necessity of core.async (the alternative is to descend to locks world). Saludos, Nahuel Greco. On Thu, Oct 9, 2014 at 9:07 AM, Fergal Byrne wrote: > Hi Nahuel, > > I think it's worth stepping back from discussing solutions and have a look > at the problem. If I'm reading things right you need the following: > > 1. Producer produces values one at a time - should not step until last > value has been handled correctly elsewhere. > 2. Middleman needs to consume one value and (potentially) retry an > external service until it can verify correct handling. > 3. Producer should not interpret the consumption of a value as a signal to > proceed. > > You also seem to want the following: > > a. Use core.async > b. Make the solution "elegant" > > That's all fine, but it seems like a bit of a golden hammer. Your problem > is precisely not the kind of problem core.async channels are designed to > solve. Channels are there to provide decoupling of producer and consumer, > whereas you, in fact, need the kind of coupling provide by function calls. > > Channels are for when you don't want to know how or when your product is > handled. You're finished, you throw the product on a channel, and you move > on to making your next product. All you ever find out is if/that your > product has been picked off the channel. > > Function calls are for when you do need to know what happened to your > product, and when it has all happened, because you can't move on until the > last thing has been done. > > Just call the middleman in synchronous code in your producer, with one > value, and look at its return value to tell you what to do next. You get > your blocking semantics (1-3) and you also get information about success or > failure. > > Using channels, consumption is the only information the producer hears > back. To tell the producer you've completed your mission as middleman, > you'll need another channel. If you really want to use core.async: > > (>! c v) ; blocks until consumed > (respond-to ( ...do expensive stuff > > but this is just an expensive function call. > > Regards, > > Fergal Byrne > > > On Thu, Oct 9, 2014 at 11:16 AM, Eduard Bondarenko > wrote: > >> I think the point is to not generate values by producer if external >> service is not available >> "The producer only unparks when the value is effectively consumed by >> the external service. That's my objective." >> >> "external ready" channel here serves as a latch that stops producer >> generating value. >> >> On Thu, Oct 9, 2014 at 6:39 AM, Fluid Dynamics >> wrote: >> > On Monday, October 6, 2014 9:36:59 AM UTC-4, edbond wrote: >> >> >> >> Add one more chan, "external ready". >> >> Put :ok there to let producer generate new value. >> >> >> >> producer: >> >> - read from "external ready" >> >> - generate value >> >> - put into "outgoing" chan >> >> >> >> client: >> >> - contact external server, put in "external ready" if ok >> >> - read from "outgoing" chan >> >> - send to external >> >> >> >> Handle exceptions and loop where you need. >> > >> > >> > If you're not reading from "outgoing" until the external server is >> known to >> > be ready, you don't need the "external ready" channel. Backpressure on >> the >> > "outgoing" channel will suffice to keep the producer from overrunning >> the >> > consumer in this case. >> > >> > -- >> > You received this message because you are subscribed to the Google >> > Groups "Clojure" group. >> > To post to this group, send email to clojure@goog
Re: core.async: peek the next value from a channel without consuming it
Fergal: I knew about the ack channel solution (note I mentioned it a while couple of mails ago), I was trying to avoid it with the objective of making the producer code extra simple. Also note, in core.async the producers aren't totally decoupled from consumers, there is an implicit consumer->producer signalling in the form of channel backpressure. The only way to decouple them totally is to use "infinitely" sized or dropping queues (something like Erlang tries to do given enough memory, where the only form of backpressure are explicit acks). The peek operation I proposed is a way to fine control that backpressure signalling. In POSIX the select() operation doesn't peeks the value but can be used to know if there is a value present without consuming it. In contrast, I think alts! complects three operations: 1- blocking until new value / can write one 2- reading/putting it 3- when reading, consuming it. Besides the alternative solutions for the producer code (waiting on ack channel, alts! before computing the value) my original question remains unanswered: There is something in core.async implementation/design/roadmap preventing adding a peek operation? I was hoping to avoid a deep dive on core.async code :) Saludos, Nahuel Greco. On Thu, Oct 9, 2014 at 9:39 AM, Fergal Byrne wrote: > Hi Nahuel, > > Thanks for the clarification. Multiple producers, single middleman is a > different problem from the one we (or at least I) thought we were dealing > with. In that case, the put your ack channel in your product, block on the > ack channel method is the right one. > > (loop [...] > ..something expensive... > (let [ack (chan)] > (>! c [v ack]) > (respond-to ( (recur ...)) > > Regards, > > Fergal > > On Thu, Oct 9, 2014 at 1:21 PM, Nahuel Greco wrote: > >> Fluid: as you said, backpressure on the outgoing channel will be >> sufficient to avoid producer to overrun consumer (without using any extra >> ack-channel), but the producer will compute a new not-yet-used value before >> blocking on sending it to consumer. That's what I want to avoid. >> >> I can also use alts! on the producer to check if he can write to the >> channel before computing the value, but I wanted to keep the code in the >> producer in the simplest form possible (a simple (>! c v) parking until all >> parties consume the value, avoiding an ack-chan or an alts!) . >> >> Eduard: Exactly. >> >> Fregal: If middleman is managing all the communication with the external >> service for *multiple* producers, then it can't be reduced to a simple >> synchronous function call from a producer, hence the necessity of >> core.async (the alternative is to descend to locks world). >> >> >> >> Saludos, >> Nahuel Greco. >> >> On Thu, Oct 9, 2014 at 9:07 AM, Fergal Byrne > > wrote: >> >>> Hi Nahuel, >>> >>> I think it's worth stepping back from discussing solutions and have a >>> look at the problem. If I'm reading things right you need the following: >>> >>> 1. Producer produces values one at a time - should not step until last >>> value has been handled correctly elsewhere. >>> 2. Middleman needs to consume one value and (potentially) retry an >>> external service until it can verify correct handling. >>> 3. Producer should not interpret the consumption of a value as a signal >>> to proceed. >>> >>> You also seem to want the following: >>> >>> a. Use core.async >>> b. Make the solution "elegant" >>> >>> That's all fine, but it seems like a bit of a golden hammer. Your >>> problem is precisely not the kind of problem core.async channels are >>> designed to solve. Channels are there to provide decoupling of producer and >>> consumer, whereas you, in fact, need the kind of coupling provide by >>> function calls. >>> >>> Channels are for when you don't want to know how or when your product is >>> handled. You're finished, you throw the product on a channel, and you move >>> on to making your next product. All you ever find out is if/that your >>> product has been picked off the channel. >>> >>> Function calls are for when you do need to know what happened to your >>> product, and when it has all happened, because you can't move on until the >>> last thing has been done. >>> >>> Just call the middleman in synchronous code in your producer, with one >>> value, and look at its return value to tell you what to do next. You get >>> your blocking semantics (1-3)
Re: core.async: peek the next value from a channel without consuming it
Fergal: readability when using an ack channel is improved, you are totally right on this point and is probably the most important argument for using acks, besides there is no peek currently on core.async (note if you have a long producer-consumer1-consumerN chain everyone must implement the ack procedure). But I think you are wrong when you say a middleman using peek can only support a single product at time and no multiple producers batching. Without thinking about producer code form, peeking + consuming (implicit "ack") is the same thing as doing consuming + explicit ack. Sure, you need a multiple channels alts!-like peek operation. What can change the equation is to use a single ack per multiple values, I think peek can't support something like that, but that also changes the design of the producer code. Note "waiting until the service is ready before taking from the channel" without using acks or peek+consume can introduce race conditions where the service goes down just after sensing it ready and consuming the producer value. Just to be clear, I know acks solves this (changing producer code), and I currently use an acks schema. I'm only curious about why a peek operation wasn't included in core.async and the feasibility of adding it. Thanks for your replies. Saludos, Nahuel Greco. On Thu, Oct 9, 2014 at 11:04 AM, Fergal Byrne wrote: > Hi Nahuel, > > If you look at the definition of "simple" it means "not compound". In your > case, you are trying to have a single thing (the channel) do two jobs: > convey the value, and control the producer. This is not simple, and makes > the producer trust that the middleman will always respect this hidden > dependence. It also hides your intent elsewhere (anyone reading your code > would assume that the producer does not have to wait). > > In this case (the ack channel), you are adding a couple of lines of code > (to make the ack channel and to block until it comes back), but you are > simplifying the producer when you do this, not complicating it. The (!< c > [v ack]) does one thing - I'm finished my expensive op, please deal with > it. The (respond-to ( been processed, now I can move on. > > The code is self-documenting. The producer finishes its work, puts the > stuff on a channel with a self-addressed envelope, and then immediately > blocks for the ack. It couldn't possibly be simpler than this. > > The decoupling channels provide is exactly that: everything except > backpressure is decoupled. You're trying to recouple the producer and > middleman, by trying to make a non-atomic thing atomic. > > You're also designing the middleman based on the needs of the producer. > With your design, the middleman can only handle one product at a time. With > the put-ack design, the middleman could have a longer queue, construct > batches of similar values, and more efficiently use the external service. > You're also creating a bottleneck, because other producers are all blocked > until your middleman has got the external service to work with your value. > > Either the external service's ability to complete is based on something in > your value or not. If not, then have the middleman wait until the service > is ready (as someone suggested) before taking from the channel - this > achieves your goals with backpressure. If you do need to know something in > the value, then take the value and spin up a go block to retry the service > (passing it the ack channel, so it can unblock the producer), and move on. > > Adding peek to channels couldn't be hard (it's open source after all!), so > you could do it for yourself if you think it would give you any value. But > I can give you a fairly precise estimate on how long a PR for this would > sit in Rich's in-tray.. > > Cheers, > > Fergal > > > On Thu, Oct 9, 2014 at 2:01 PM, Nahuel Greco wrote: > >> Fergal: I knew about the ack channel solution (note I mentioned it a >> while couple of mails ago), I was trying to avoid it with the objective of >> making the producer code extra simple. >> >> Also note, in core.async the producers aren't totally decoupled from >> consumers, there is an implicit consumer->producer signalling in the form >> of channel backpressure. The only way to decouple them totally is to use >> "infinitely" sized or dropping queues (something like Erlang tries to do >> given enough memory, where the only form of backpressure are explicit >> acks). The peek operation I proposed is a way to fine control that >> backpressure signalling. >> >> In POSIX the select() operation doesn't peeks the value but can be used >> to know if there is a value present without cons
Re: core.async: peek the next value from a channel without consuming it
Leon: your :useless example is equivalent to one using the hypothetical peek operation and to the ack-channel solution, but what you define as ":useless multithreading" because at one time only one thread is working, is a valid synchronization scenario and the one I was searching for. The objective here was not to max CPU usage with these two threads / go-blocks. As I said in a previous mail "maybe you want to reserve the cpu cycles for other tasks, or the producer needs a confirmation for other purposes before computing or requesting the value from another party, this is a distilled example". Also think the producer after sending the computed value and before sending the :useless signal can do other things, maybe contacting other services to pre-fetch data used in the next value. Also the :useless example needs more code on the producer side than a simple (>! c v). Given there is no peek operation and the producer code must participate explicitly in the synchronization, I prefer the ack solution over the :useless one. You are right about impossibility of using alts! in the producer code to check if the chan can be written to before computing the value. I forgot alts! is a function, not a macro, and you can't pass expressions to it to be evaluated when the chan becomes available to write. Your last sample seems an useful way to manage simple stateless single-value producers from the consumer, but producers can be long-running go-blocks with their own state and with channels to other services, so I think is a little off base the original question. Saludos, Nahuel Greco. On Thu, Oct 9, 2014 at 4:16 PM, Leon Grapenthin wrote: > On Thursday, October 9, 2014 2:22:50 PM UTC+2, Nahuel Greco wrote: >> >> Fluid: as you said, backpressure on the outgoing channel will be >> sufficient to avoid producer to overrun consumer (without using any extra >> ack-channel), but the producer will compute a new not-yet-used value before >> blocking on sending it to consumer. That's what I want to avoid. >> > > You can avoid this very easily. Everytime before the producer expensively > calculates its next value to put it on the channel, make it put a cheaply > calculated value, e. g. the keyword :useless, on the channel instead. > > Now on the consumer side you can do this: > > 0. Blocking (immediate take): Consume the keyword :useless = The producer > will begin production > 1. *This is what you want from peek! *Blocking take = Waiting for the > producer to have produced the expensive value, consume it *but the > producer won't calculate the next value (because he puts the :useless > keyword which won't be consumed until later)* > 2. Wait for external service to be ready, put value there > 3. Go to step 1 trigger production of the next value > > Assuming the producer and the consumer run on different threads, what have > you won by introducing step 0? > > 1. The producer thread can't begin to work until the consumer thread did > his work > 2. The consumer thread can't begin to work until the producer thread did > his work > > = At every point in time only one thread performs. Entirely :useless > multi-threading. > > I can also use alts! on the producer to check if he can write to the >> channel before computing the value, [...] >> > You can't > > > >> [...] >> > > >> Fregal: If middleman is managing all the communication with the external >> service for *multiple* producers, then it can't be reduced to a simple >> synchronous function call from a producer, hence the necessity of >> core.async (the alternative is to descend to locks world). >> > > If I understand you right, you would want to start production of multiple > values in parallel, wait for the first to be ready, then put that to the > external service and loop. Here core.async can be of help. E. g. > (defn exp-calcs > [] > #{(a/thread calc-exp-val-1) > (a/thread calc-exp-val-2) > (a/thread calc-exp-val-3) > (a/thread calc-exp-val-4) > (a/thread calc-exp-val-5) > ; ... > }) > > (loop [chans (exp-calcs)] > (let [[val ch] (a/alts!! (seq exp-calcs))] > ;; wait for external service, put val there > > ;; also have the cancellation ch in chans and use it to guard the > ;; following form > (let [chans (disj chans ch)] > (recur (if (seq chans) >chans >(exp-calcs)) > > > > Again, no peek required. > > >> >> >> >> Saludos, >> Nahuel Greco. >> >> On Thu, Oct 9, 2014 at 9:07 AM, Fergal Byrne >> wrote: >> >>> Hi Nahuel, >>> >>> I think it's worth stepping back
Re: Modelling in Clojure
Maybe we need some sort of lazy map where: (def m (assoc-computed {:first-name "Robert" :last-name "Plankton"} :full-name #(str (:first-name %) " " (:last-name % ;; will call the function to compute the value and will memoize it: (:full-name m) ;; now the memoized value is returned without calling the function (:full-name m) ;; equality / hashing will trigger computation+memoization of all m ;; computed keys if they aren't computed yet: (= m other-map) Computing functions must be pure, so m internally is a mutable object but you can't really distinguish it from an immutable one :) Saludos, Nahuel Greco. On Sat, Oct 18, 2014 at 5:02 PM, Mark Engelberg wrote: > I think all of James' points about the proven value of structuring an > application primarily around data rather than a complex API are right on > point. It is one of the things I love about the Clojure philosophy. > > But there's nothing about the value of data-driven development that > requires data lookups and data computations to be so different. There's > plenty of room for Clojure to have continued evolution in this area and > still preserve the essence of its approach. > > For example, consider that several years ago, Rich declared that Clojure > would never have a simple mutable box. But lo and behold, now we have > volatiles. Consider the rise of records, protocols, and components -- a > lot of judiciously applied OOish concepts. > > I really enjoy introducing Java programmers to the Clojure way of thinking > about data. But when I do, I like to explain the current thinking in the > Clojure community, talk about some of the most triumphant success stories > (e.g., Ring), acknowledge some of the pain points, talk about some of the > ways that Clojure has grown to handle other data modeling pain points, and > some of the ways that Clojure may continue to grow. > > -- > 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: core.async
Very nice! Selectable channels FTW. Btw, are you aware of the Erlang selective-receive model? Is often very overlooked but it showed big advantages over unfiltered channels. See this: http://www.erlang.se/euc/05/1500Wiger.ppt Saludos, Nahuel Greco. On Fri, Jun 28, 2013 at 4:06 PM, Rich Hickey wrote: > I've blogged a bit about the new core.async library: > > http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html > > Please try it out. > > Thanks, > > Rich > > -- > -- > 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/groups/opt_out. > > > -- -- 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/groups/opt_out.
Re: core.async
I forgot the second Ulf Wiger link, related to the previous one: http://www.infoq.com/presentations/Death-by-Accidental-Complexity Saludos, Nahuel Greco. On Fri, Jun 28, 2013 at 4:46 PM, Nahuel Greco wrote: > Very nice! Selectable channels FTW. > > Btw, are you aware of the Erlang selective-receive model? Is often very > overlooked but it showed big advantages over unfiltered channels. See this: > http://www.erlang.se/euc/05/1500Wiger.ppt > > Saludos, > Nahuel Greco. > > > On Fri, Jun 28, 2013 at 4:06 PM, Rich Hickey wrote: > >> I've blogged a bit about the new core.async library: >> >> http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html >> >> Please try it out. >> >> Thanks, >> >> Rich >> >> -- >> -- >> 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/groups/opt_out. >> >> >> > > -- -- 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/groups/opt_out.
Re: Clojure Objects
Maybe a better word for complecting is "entangling". Saludos, Nahuel Greco. On Tue, Nov 24, 2015 at 5:19 AM, Colin Yates wrote: > > (Clojure's vocabulary is not to be questioned...why say "conflate" or > "confuse" when you can say "complect" to reinforce in-group membership ?) > /rant > > THANK YOU! I can't count the number of times I've had to restrain myself > from an apoplectic rant about this hideous non-word. What is wrong with > "complicate" FFS?! > > Careful - ‘complect’ has a very specific meaning which is compatible with > the notion of conflate. Confusion on the other hand is far more about > familiarity. The whole point of the Simple made Easy talk was to propose > that the ‘complexity’ of something is a mathematical measurement (loosely, > the number of concerns in that atomic thing). Simple on the other hand was > about your familiarity with the thing. > > Confusion is somewhat orthogonal to complexity as it is more to do with > the _understanding_ of the thing. > > > On 23 Nov 2015, at 22:23, Gregg Reynolds wrote: > > > On Nov 23, 2015 6:34 AM, "Bobby Bobble" wrote: > > > > let's not forget that Clojure's datastructures are objects. They respond > to messages like seq, first, rest etc (which requires a bit more complexity > than what Clojurians hail as "just data", which would be like > 1010101101010100011011...what Clojurians really mean by that > term is something like "uniform access to objects") > > Hmm. If by "object" you mean entity, thing, value, etc. - i.e. > mathematical structure - then I'd agree, but in my view Clojure does not > involve OO "objects" in any way, _conceptually_. "This function is > defined on that type" != "that type 'responds to' this function" . > > > > > (Clojure's vocabulary is not to be questioned...why say "conflate" or > "confuse" when you can say "complect" to reinforce in-group membership ?) > /rant > > THANK YOU! I can't count the number of times I've had to restrain myself > from an apoplectic rant about this hideous non-word. What is wrong with > "complicate" FFS?! > > > > > anyway to the point, it depends what you mean by "objects". > > > > > What you propose is to use maps as a kind of namespace for functions. > It's a good idea. I use this pattern too. Really, namespaces should be > maps...actually I think there was a project called Kiss to that end. > > To the OP's original point: you can view functions as data, but I find > myself moving toward a view of data as functions. E.g. it's as nullary fns. > > > > But real OO, as realized by Smalltalk and Self is about messaging, not > objects. > > Thank you again. Objective C is another good example. Dunno why they > called it OO in the first place. > > AFAIA there's no way in Clojure to represent "the invocation of a function > on a thing" the way you can represent "the sending of a message to an > object" in Smalltalk. > > Not quite sure what you mean, but with stuff like core.async and protocols > it's possible to support an explicit msg - passing idiom in Clojure. But I > think I agree with you. It would be something you build on more primitive > notions. > > Gregg > > -- > 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 yo
Re: [ANN] akar 0.1.0
Hi Rahul, Akar seems very nice! It works in Clojurescript? Saludos, Nahuel Greco. On Tue, Jul 5, 2016 at 11:38 AM, Rahul Goma Phulore < rahul.phulore@gmail.com> wrote: > Hi, all. > > I am quite excited to announce my project Akar – > https://github.com/missingfaktor/akar. It's a pattern matching library > for Clojure, wherein the patterns are first class values (just functions, > actually). Akar patterns can be manipulated, composed, abstracted over, > like any other functions. In fact, this is exactly how various pattern > operations, such as guards, alternation, and views are implemented in Akar. > The library also features a syntactic layer that makes common use cases > convenient, but at the same time stays true to the first-class spirit of > the core model. > > The library comes with a full-blown *tutorial* > <https://github.com/missingfaktor/akar/blob/master/TUTORIAL.md> and also > covers some FAQs > <https://github.com/missingfaktor/akar/blob/master/FAQs.md>. > > I made the first release - 0.1.0 - today. > > I hope you guys like it, and find it useful! Feedback, constructive > criticism, PRs are most welcome. > > Best, > Rahul > > -- > 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: Natively Compiled Clojure
Check the clojure-py2 project, they plan to use LLVM to generate native modules (as C compiled) for Python. When that objective is reached probably you will have almost all the machinery to compile python-less native binaries: http://lanyrd.com/2013/clojurewest/sccgmm/ Saludos, Nahuel Greco. On Fri, Jan 25, 2013 at 12:18 PM, Marko Kocić wrote: > > > On Friday, January 25, 2013 6:12:07 AM UTC+1, Mikera wrote: >> >> A natively compiled Clojure would be very very interesting (perhaps >> targeting LLVM?) >> >> However it would also be very hard to implement. Clojure depends on a lot >> of features provided by the JVM (JIT compilation, interop with Java >> libraries, garbage collection being the most significant ones). It would be >> very hard to reimplement all of these from the ground up. The JVM is >> already a very good host platform, why fix something that isn't broken? >> > > What about native ClojuresScript? It doesn't have to implement everything > Clojure have already, and many people could consider it good enough > alternative to Clojure. I could personally live without runtime macros and > eval if it would gain me small and performant native executable. > > >> Arguably the effort would be better spend improving the JVM with extra >> features that would help Clojure (e.g. TCO). >> >> On Tuesday, 22 January 2013 00:29:54 UTC+8, octopusgrabbus wrote: >>> >>> I use Clojure primarily as a very reliable tool to aid in data >>> transformations, that is taking data in one application's database and >>> transforming it into the format needed for another applications' database. >>> >>> So, my question is would a natively compiled Clojure make sense or turn >>> the language into something that was not intended? In almost all instances >>> I have not found a problem with Clojure's execution speed so my question is >>> not about pro or anti Java. >>> >>> 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 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
Question about "special" macroexpansions
The (.method1 obj) => (. obj method1) macroexpansion is defined as an "special" one, and I suppose the macroexpansion (Integer/MAX_VALUE) => (. Integer MAX_VALUE) is another one. Correct me if I'm wrong, but I think they are "special" because you reference the macro not by the first symbol in the expression but as an special punctuation syntax. My question is, which other "special" macroexpansions exists? There is a complete list somewhere? Where these macros are located in the Clojure compiler source? Saludos, Nahuel Greco. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Idea around SCMs and Clojure
What about storing the vars definitions in Datomic? Maybe augmented with semantic information ("added defmethod", "redefined function", etc). Saludos, Nahuel Greco. On Wed, Jul 18, 2012 at 5:19 AM, Mark Derricutt wrote: > On 17/07/12 10:27 PM, N8Dawgrr wrote: > > > In a nutshell its about why use files for source in Clojure, can we do > better? > > Almost sounds like you're wanting the Smalltalk "image" along with something > like Monticello - the smalltalk distributed version control system ( > versioning at the function layer would be awesome ). > > http://wiresong.ca/monticello/ > > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Idea around SCMs and Clojure
Check this project announced today in the Datomic ml: http://github.com/jonase/scape "Scape is quite ambitious. The idea is is to use the ClojureScript analyzer to emit Datomic transaction data containing useful information about some codebase and putting the data in a datomic database so the program becomes queriable via datalog. This could possibly be used for static analysis of Clojure code." Saludos, Nahuel Greco. On Tue, Jul 17, 2012 at 11:04 AM, Steve Tickle wrote: > It would be more interesting to see a version control system based on > storing an abstract syntax tree and then using a pretty printer when the > files are checked out. > In one fell swoop you remove the code-styling wars as everyone can have > their own coding style and maintain consistency with everyone else. > It also gives the versioning system knowledge of the code so you can diff > functionality rather than the textual representation of that functionality. > > Combine an editor with the pretty printing/ASTVersioning and you have a > proper integrated development environment! > > SteveT > > On Tuesday, 17 July 2012 11:27:41 UTC+1, N8Dawgrr wrote: >> >> Hi All, >> >> One of my first posts to Clojure mailing list. I had an idea around SCMs >> and Clojure. I'd basically like to put the idea out there and get some >> feedback. I hope I'm not breaking any etiquette linking to my blog post but >> I've outlined the idea here: >> >> http://clojurian.blogspot.co.uk/ >> >> In a nutshell its about why use files for source in Clojure, can we do >> better? >> >> Regards, >> >> Nathan > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: [viewing clojure datastructures] Is there something better than clojure.inspector?
Another nice and simple addition to clojure.inspector would be add auto-refreshing, so you can pass a reference and it and will display always his latest version (maybe by using a watcher). It will be nice for live debugging. Saludos, Nahuel Greco. On Wed, Aug 22, 2012 at 5:58 PM, Denis Labaye wrote: > Hi everyone, > > The clojure.inspector functions are ... mmm ... a bit "rough on the edge" > =) > > Is there any lib that provide better support for exploring > Clojure data-structures? > > I am surprised I didn't found anything on Google, GitHub, ... > Data-structures are at the core of Clojure, so being able to view / > explore them seems a basic need to me. > > For example: > > ;; this works fine > (clojure.inspector/inspect-tree (range 10)) > > ;; this breaks > (clojure.inspector/inspect-tree (range)) > > It seems to me that it would be *trivial*™ to implement a viewer that > would be able to display (possibly infinite) lazy nested data structures. > > Any ideas? > > Cheers, > > Denis > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: [viewing clojure datastructures] Is there something better than clojure.inspector?
You can set the clj-ns-browser browser to auto-refresh but you need to utilize a full browser window just to watch a Var, and also the value not as nicely displayed as using clojure.inspector. A nice addition to clj-ns-browser will be to make possible create many auto-refreshing clojure.inspector like windows out of browser selections, so many Vars can be watched live in the least screen state possible. Saludos, Nahuel Greco. On Wed, Aug 22, 2012 at 6:33 PM, Frank Siebenlist < frank.siebenl...@gmail.com> wrote: > Check out clj-ns-browser ("https://github.com/franks42/clj-ns-browser";). > > When a var is defined, you can look at it's value, which is presented with > pprint, which means that most data structures are nicely displayed. > > When the value is a list/tree-like data structure, you can bring up Rich's > original tree browser with the click of a button to look at the values. > (that widget should really be rewritten as it's look and feel good be > improved… but it works!) > > Furthermore, there is a menu button that turns on an auto-refresh for the > var's displayed value such that you can follow the var's value near > real-time. > > This may help with your requirements... > > Enjoy, Frank. > > > On Aug 22, 2012, at 1:58 PM, Denis Labaye wrote: > > > Hi everyone, > > > > The clojure.inspector functions are ... mmm ... a bit "rough on the > edge" =) > > > > Is there any lib that provide better support for exploring Clojure > data-structures? > > > > I am surprised I didn't found anything on Google, GitHub, ... > > Data-structures are at the core of Clojure, so being able to view / > explore them seems a basic need to me. > > > > For example: > > > > ;; this works fine > > (clojure.inspector/inspect-tree (range 10)) > > > > ;; this breaks > > (clojure.inspector/inspect-tree (range)) > > > > It seems to me that it would be trivial™ to implement a viewer that > would be able to display (possibly infinite) lazy nested data structures. > > > > Any ideas? > > > > Cheers, > > > > Denis > > > > > > -- > > You received this message because you are subscribed to the Google > > Groups "Clojure" group. > > To post to this group, send email to clojure@googlegroups.com > > Note that posts from new members are moderated - please be patient with > your first post. > > To unsubscribe from this group, send email to > > clojure+unsubscr...@googlegroups.com > > For more options, visit this group at > > http://groups.google.com/group/clojure?hl=en > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: [viewing clojure datastructures] Is there something better than clojure.inspector?
You can set the clj-ns-browser browser to auto-refresh but you need to utilize a full browser window just to watch a Var, and also the value not as nicely displayed as using clojure.inspector. A nice addition to clj-ns-browser will be to make possible create many auto-refreshing clojure.inspector like windows out of browser selections, so many Vars can be watched live without using too much screen space. Saludos, Nahuel Greco. On Wed, Aug 22, 2012 at 6:33 PM, Frank Siebenlist < frank.siebenl...@gmail.com> wrote: > Check out clj-ns-browser ("https://github.com/franks42/clj-ns-browser";). > > When a var is defined, you can look at it's value, which is presented with > pprint, which means that most data structures are nicely displayed. > > When the value is a list/tree-like data structure, you can bring up Rich's > original tree browser with the click of a button to look at the values. > (that widget should really be rewritten as it's look and feel good be > improved… but it works!) > > Furthermore, there is a menu button that turns on an auto-refresh for the > var's displayed value such that you can follow the var's value near > real-time. > > This may help with your requirements... > > Enjoy, Frank. > > > On Aug 22, 2012, at 1:58 PM, Denis Labaye wrote: > > > Hi everyone, > > > > The clojure.inspector functions are ... mmm ... a bit "rough on the > edge" =) > > > > Is there any lib that provide better support for exploring Clojure > data-structures? > > > > I am surprised I didn't found anything on Google, GitHub, ... > > Data-structures are at the core of Clojure, so being able to view / > explore them seems a basic need to me. > > > > For example: > > > > ;; this works fine > > (clojure.inspector/inspect-tree (range 10)) > > > > ;; this breaks > > (clojure.inspector/inspect-tree (range)) > > > > It seems to me that it would be trivial™ to implement a viewer that > would be able to display (possibly infinite) lazy nested data structures. > > > > Any ideas? > > > > Cheers, > > > > Denis > > > > > > -- > > You received this message because you are subscribed to the Google > > Groups "Clojure" group. > > To post to this group, send email to clojure@googlegroups.com > > Note that posts from new members are moderated - please be patient with > your first post. > > To unsubscribe from this group, send email to > > clojure+unsubscr...@googlegroups.com > > For more options, visit this group at > > http://groups.google.com/group/clojure?hl=en > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Map-destructuring a non-associative structure, non documented behavior?
I can't find the documentation for this behaviour: (let [{x :b :as y} '(:a 1 :b 2)] [x y]) ;=> [2 {:a 1, :b 2}] It seems as if the list in the init-expr is converted first to an associative structure and then destructured. But that behaviour doesn't seems to be documented, the map destructuring documentation only talks about destructuring of associative structures, and also there is nothing about binding the :as expression to the resultant associative structure instead of the initial init-expr. Is this documented somewhere? Is an intended behaviour assured to be present in the future Clojure versions? Saludos, Nahuel Greco. -- 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