[ANN] Citrus (Scrum) 3.0.0 — State management library for Rum

2017-08-28 Thread Khalid Jebbari
Any API change ? Or just renaming?

-- 
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: ref strange behavior

2017-08-28 Thread Gary Verhaegen
I wasn't satisfied with the various answers to both this thread and
the StackOverflow question, so I spent a bit more time digging; it
turns out this was a bug in the range implementation that was fixed in
1.9.0-alpha11. I've added a bit more details on StackOverflow [1]; the
full story is on the ticket [2].

[1] 
https://stackoverflow.com/questions/39054911/strange-behavior-of-clojure-ref/45919119#45919119
[2] https://dev.clojure.org/jira/browse/CLJ-1914

On 23 August 2016 at 13:09, Sergei Koledov  wrote:
> Hello,
>
> I had a problem when I run the following code:
>
> (defn get-task [tasks]
>   (dosync
> (let [task (first @tasks)]
>   (alter tasks rest)
>   task)))
>
> (defn worker [& {:keys [tasks]}]
>   (agent {:tasks tasks}))
>
> (defn worker-loop [{:keys [tasks] :as state}]
>   (loop [last-task nil]
> (if-let [task (get-task tasks)]
>   (recur task)
>   (locking :out (println "Last task: " last-task
>   state)
>
> (defn create-workers [count & options]
>   (->> (range 0 count)
>(map (fn [_] (apply worker options)))
>(into [])))
>
> (defn start-workers [workers]
>   (doseq [worker workers] (send-off worker worker-loop)))
>
> (def tasks (ref (range 1 1000)))
>
> (def workers (create-workers 100 :tasks tasks))
>
> (start-workers workers)
> (apply await workers)
>
> Description: I have several agents (100 in my case). Each agent running in a
> separate thread. All agents share the one ref with the collection of tasks
> (range of longs in my case). Each agent get tasks from the collection (in
> transaction) one by one until the collection becomes empty and then prints
> the last task which it handle. However, when I run this code it looks like
> the collection of tasks suddenly becomes empty and workers handle only
> portion of all tasks (average 25-40% of all number).
>
> This code behave as I expected, when I create only one agent or use explicit
> locking in get-task function:
>
> (defn get-task [tasks]
>   (locking :lock
> (dosync
> (let [task (first @tasks)]
>   (alter tasks rest)
>   task
>
> I run this code on the Clojure 1.8.0
> java version "1.8.0_91"
> Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
> Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
>
> Can anyone tell me, what am I doing wrong, or it really looks like a bug in
> the clojure STM?
> I already asked this question on stackoverflow.com
> (http://stackoverflow.com/questions/39054911/strange-behavior-of-clojure-ref),
> but so far nobody has been able to help me.
>
> P.S. Sorry for my english skill.
>
> --
> 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: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-28 Thread Reid McKenzie
FWIW I wrote a library around defining tagged map 
types https://github.com/arrdem/guten-tag and used it heavily in the 
Grimoire implementation almost entirely to my satisfaction. No idea if 
anyone else ever picked it up, and due to implementation details of 
Clojure's let map destructuring you can't just treat one of my map wrapper 
types as a normal Clojure map and :keys it apart but it works great with 
core.match.

Reid

On Friday, August 25, 2017 at 1:30:37 PM UTC-7, tbc++ wrote:
>
> >> they're a little nicer to type and read
>
> And that's where I have to disagree. The problem with most of these 
> options is they complect ordering with meaning. 
>
> [:image/file "/images/image" :jpeg]
>
> Here I have no idea what these values mean. I have to have out-of-band 
> information about what offset in the vector corresponds to what value. 
> Functions have this same problem, look no further than `cons` vs `conj` to 
> see potential confusion on argument ordering. 
>
> So why don't we only use maps for function arguments? Well mostly to make 
> the functions easier to manipulate by humans. But some of the best 
> libraries for web APIs (AWS) that I've used have used almost an exclusively 
> map based interface. 
>
> Once again I have to repeat my mantra about DSLs. Don't start with DSLs. 
> Start with maps. Build everything off of maps. They're extensible, easy to 
> introspect, and can drive a host of metaprogramming algorithms. If maps are 
> to hard to understand, build constructor functions on top of them. Then 
> finally build a DSL on top, if you need it. 
>
> Frankly, I have so many things I have to remember during programming. I'd 
> much rather see a very uniform map-based interface. Than any sort of nested 
> vectors, tagged values, or anything else. 
>
> Surely we can't say that this:
> >> [[:image/file :image/web] :image.file/path "/images/image" 
> :image.file/format :jpeg :image.web/url "www.myimage.com/image"]
>
> Is a better interface than:
>
> {:image.file/path "/images/image"
>  :image.file/format :jpeg
>  :image.web/url "www.myimage.com/image"}
>
> And as I said before, spec is designed from the start to support data in 
> this format. Stating "this is a file", "this is a web image". Is just book 
> keeping that doesn't need to be done. Is a map a :image/web? Well check its 
> members and see if they match the spec. If they match, then you have a 
> :image/web. No need for sum types, tags, wrapping values in vectors. Simply 
> state what a thing should have for it to conform to an interface, and 
> forget whatever else might be in there. It couldn't be simpler. 
>
> On Fri, Aug 25, 2017 at 11:59 AM, Didier > 
> wrote:
>
>> Thanks for everyone's great input.
>>
>> Currently, I see the big distinction being concise vs extension. Maybe 
>> for streaming variants would be better as the format would be smaller to 
>> transfer over a wire. And for small short lived programs, or things you 
>> know won't need extension, variants offer a slightly more convenient 
>> structure to work with.
>>
>> I think both can be specced easily. S/or a few s/tuple to spec a variant. 
>> And multi-spec over a set for the map version.
>>
>> I'd like to explore then the issue of extensibility with variants. How 
>> would you extend them, is there really no way? This is some of my 
>> brainstorming thoughts.
>>
>> 1) How to design a variant of more then one value?
>>
>>
>> 1.1)
>>
>> I know this is a standard variant of one value:
>>
>> [:image/web "www.myimage.com/image.jpg"]
>>
>> I believe to extend it to more values, you would do:
>>
>> [:image/file "/images/image" :jpeg]
>>
>> That is, you'd threat it as a constructor function, which creates an 
>> :image/file type and takes an ordered list of arguments. This way, each 
>> variant type can even be overloaded on their arguments the way you'd 
>> overload a function.
>>
>> [:image/file "/images/image"]
>>
>> Can default to format :png for example, when using the one arg 
>> constructor.
>>
>> 1.2)
>>
>> An alternative is to keep variants as vector pairs, and nest them.
>>
>> [:image/file [:image/file-path "/images/image"] [:image/file-format:jpeg]]
>>
>> In this form, variants are more like their map counterpart. Each element 
>> is named and itself a variant.
>>
>> 1.3)
>>
>> You could also decide to limit variants to strict pairs, so the second 
>> element of any variant is either a variant or a vector of variants.
>>
>> [:image/file [[:image/file-path "/images/image"] 
>> [:image/file-format:jpeg]]]
>>
>> Now with both these forms, 1.2 and 1.3, if you threat them again as 
>> constructor functions, you now have a form of named parameter on your 
>> constructor, allowing mixed order.
>>
>> 1.4)
>>
>> At this point, the variant has become pretty similar to a map, losing in 
>> verbosity over it even. There's just one advantage, the type is not a 
>> key/value pair, which I find is more intuitive to use, no need to know the 
>> special name of key that holds th

Re: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-28 Thread Timothy Baldridge
>>  https://github.com/arrdem/guten-tag

The name alone deserves a +1. :D


On Mon, Aug 28, 2017 at 2:53 PM, Reid McKenzie  wrote:

> FWIW I wrote a library around defining tagged map types
> https://github.com/arrdem/guten-tag and used it heavily in the Grimoire
> implementation almost entirely to my satisfaction. No idea if anyone else
> ever picked it up, and due to implementation details of Clojure's let map
> destructuring you can't just treat one of my map wrapper types as a normal
> Clojure map and :keys it apart but it works great with core.match.
>
> Reid
>
> On Friday, August 25, 2017 at 1:30:37 PM UTC-7, tbc++ wrote:
>>
>> >> they're a little nicer to type and read
>>
>> And that's where I have to disagree. The problem with most of these
>> options is they complect ordering with meaning.
>>
>> [:image/file "/images/image" :jpeg]
>>
>> Here I have no idea what these values mean. I have to have out-of-band
>> information about what offset in the vector corresponds to what value.
>> Functions have this same problem, look no further than `cons` vs `conj` to
>> see potential confusion on argument ordering.
>>
>> So why don't we only use maps for function arguments? Well mostly to make
>> the functions easier to manipulate by humans. But some of the best
>> libraries for web APIs (AWS) that I've used have used almost an exclusively
>> map based interface.
>>
>> Once again I have to repeat my mantra about DSLs. Don't start with DSLs.
>> Start with maps. Build everything off of maps. They're extensible, easy to
>> introspect, and can drive a host of metaprogramming algorithms. If maps are
>> to hard to understand, build constructor functions on top of them. Then
>> finally build a DSL on top, if you need it.
>>
>> Frankly, I have so many things I have to remember during programming. I'd
>> much rather see a very uniform map-based interface. Than any sort of nested
>> vectors, tagged values, or anything else.
>>
>> Surely we can't say that this:
>> >> [[:image/file :image/web] :image.file/path "/images/image"
>> :image.file/format :jpeg :image.web/url "www.myimage.com/image"]
>>
>> Is a better interface than:
>>
>> {:image.file/path "/images/image"
>>  :image.file/format :jpeg
>>  :image.web/url "www.myimage.com/image"}
>>
>> And as I said before, spec is designed from the start to support data in
>> this format. Stating "this is a file", "this is a web image". Is just book
>> keeping that doesn't need to be done. Is a map a :image/web? Well check its
>> members and see if they match the spec. If they match, then you have a
>> :image/web. No need for sum types, tags, wrapping values in vectors. Simply
>> state what a thing should have for it to conform to an interface, and
>> forget whatever else might be in there. It couldn't be simpler.
>>
>> On Fri, Aug 25, 2017 at 11:59 AM, Didier  wrote:
>>
>>> Thanks for everyone's great input.
>>>
>>> Currently, I see the big distinction being concise vs extension. Maybe
>>> for streaming variants would be better as the format would be smaller to
>>> transfer over a wire. And for small short lived programs, or things you
>>> know won't need extension, variants offer a slightly more convenient
>>> structure to work with.
>>>
>>> I think both can be specced easily. S/or a few s/tuple to spec a
>>> variant. And multi-spec over a set for the map version.
>>>
>>> I'd like to explore then the issue of extensibility with variants. How
>>> would you extend them, is there really no way? This is some of my
>>> brainstorming thoughts.
>>>
>>> 1) How to design a variant of more then one value?
>>>
>>>
>>> 1.1)
>>>
>>> I know this is a standard variant of one value:
>>>
>>> [:image/web "www.myimage.com/image.jpg"]
>>>
>>> I believe to extend it to more values, you would do:
>>>
>>> [:image/file "/images/image" :jpeg]
>>>
>>> That is, you'd threat it as a constructor function, which creates an
>>> :image/file type and takes an ordered list of arguments. This way, each
>>> variant type can even be overloaded on their arguments the way you'd
>>> overload a function.
>>>
>>> [:image/file "/images/image"]
>>>
>>> Can default to format :png for example, when using the one arg
>>> constructor.
>>>
>>> 1.2)
>>>
>>> An alternative is to keep variants as vector pairs, and nest them.
>>>
>>> [:image/file [:image/file-path "/images/image"]
>>> [:image/file-format:jpeg]]
>>>
>>> In this form, variants are more like their map counterpart. Each element
>>> is named and itself a variant.
>>>
>>> 1.3)
>>>
>>> You could also decide to limit variants to strict pairs, so the second
>>> element of any variant is either a variant or a vector of variants.
>>>
>>> [:image/file [[:image/file-path "/images/image"]
>>> [:image/file-format:jpeg]]]
>>>
>>> Now with both these forms, 1.2 and 1.3, if you threat them again as
>>> constructor functions, you now have a form of named parameter on your
>>> constructor, allowing mixed order.
>>>
>>> 1.4)
>>>
>>> At this point, the variant has become pretty simila