Right, the use of false is a special case. I'm thinking of a mouse event stream, may have a button channel that sends true or false based on the state of the mouse button. Even saying that though, I would probably opt for :clicked and :unclicked or somethig of that nature.
Timothy On Tue, Aug 27, 2013 at 9:15 AM, Brandon Bloom <brandon.d.bl...@gmail.com>wrote: > > In every use of channels I've had thus far, nil is better expressed as > an empty collection, false, 0, :tick, or some other "ground value". > > I agree completely. But I'll note that you mention false being useful... > > If you're writing completely general operators, like map, which are > *sometimes* quite useful, then you have no choice but to do something like > if-recv or explicitly test against nil. > > > It's these Rx style programming methods that make people think they > need this feature. > > I built my little Rx with channels library (asyncx) without intention to > use it directly, but because I wanted to learn how to work with channels. I > rapidly learned that the techniques are a lot more different than they > look. In particular, it's more difficult to write channel & process > combinators precisely because they are more powerful. However, in > practice, each new reusable channel/process combinator yields more > complexity than it tends to save. I'd rather intentionally choose strictly > less powerful primitives where appropriate and enforce that with > encapsulation. > > With that in mind, if I ever revisit asyncx, I'll probably define "push > sequences" or "streams" in terms of protocols and deftypes. I'd use > core.async to implement them, but only for the lowest level primitives. I'd > provide ways to get in to or out of the stream subsystem for interop with > channels, but the public interface would take IStream objects. > > > On Tue, Aug 27, 2013 at 10:58 AM, Timothy Baldridge > <tbaldri...@gmail.com>wrote: > >> All your arguments come down to this: >> >> "I have an arbitrary seq of things I want to send down a channel". It's >> exactly that concept I that I push against. Everything you've mentioned >> thus far is a data structure. Channels are not data structures they are >> concurrency management primitives, treat them as such and I doubt you'll >> ever have a need for nils in a channel. >> >> If we treat channels as ways of co-ordinating concurrent processes, then >> nil doesn't have a use case. In every use of channels I've had thus far, >> nil is better expressed as an empty collection, false, 0, :tick, or some >> other "ground value". >> >> It's these Rx style programming methods that make people think they need >> this feature. >> >> Timothy >> >> >> >> >> On Tue, Aug 27, 2013 at 8:51 AM, Mike Anderson < >> mike.r.anderson...@gmail.com> wrote: >> >>> On 27 August 2013 20:45, Timothy Baldridge <tbaldri...@gmail.com> wrote: >>> >>>> The reason for not allowing nils isn't a complex one, and basically >>>> boils down to the following: >>>> >>>> a) to avoid race conditions, we need a single value to signal "the >>>> channel is closed". As mentioned, nil is the obvious choice for this as it >>>> matches lazy seqs and fits well with the rest of clojure: >>>> >>>> >>> Agreed that you want a single sentinel value. >>> >>> It doesn't match lazy-seqs at all though: lazy seqs can contain nils >>> just fine. There's a big difference between (next some-lazy-seq) [which >>> could be nil, indicating an empty sequence] and the actual values in the >>> seq [which could also be nil but don't indicate the end of the seq]. >>> >>> >>>> (when-let [v (<! c)] >>>> (process v)) >>>> >>>> If we chose a different value, this becomes much more ugly: >>>> >>>> (let [v (<! c)] >>>> (when-not (= v :async/closed) >>>> (process v))) >>>> >>>> >>> This can be solved easily by providing a macro or some other predicate >>> that knows how to check for the sentinel value correctly. e.g. >>> >>> (when-more [v (<! c)] >>> (process v)) >>> >>> >>>> b) I question if there are any valid uses for putting nil in a channel. >>>> With all due respect to all who have written here, thus far, every >>>> complaint about nils and channels boils down to a conversion from seqs to >>>> channels. This is the wrong way to look at the problem. Channels are >>>> co-ordination primitives not data structures. Simply because a lazy seq >>>> looks like a channel, doesn't mean that they should be treated as such. >>>> >>>> >>>> In all the core.async code I've written I've never had to put a nil in >>>> a channel, so I'm left with the uncomfortable conclusion that most >>>> complaints on this subject are contrived. I could be wrong, but I just >>>> haven't seen a valid use case yet. >>>> >>>> >>> To me it's all about consistency with other Clojure constructs. You can >>> safely put nils in sequences, vectors, lists, sets etc.. nil is a valid >>> "value" just like anything else. So why can't you put them in a channel? >>> >>> Two use cases I have encountered that motivate this: >>> >>> a) what if you want to send a sequence through a channel? Since nil as a >>> value represents the empty sequence, you have to put in some extra special >>> case handling with the current core.async model. >>> >>> b) what if you want to write generic code to send all the values in an >>> arbitrary collection through a channel? you would have to wrap/unwrap nils >>> at either end to make this work currently. >>> >>> Both of these, I think, are reasonable and common enough use cases that >>> it's worth supporting them elegantly rather than forcing users to implement >>> their own nil-wrapping functionality. >>> >>> >>>> This all being said, there really isn't a technical reason to not allow >>>> nils, it just simplifies much of the design and that probably translates to >>>> better performance. So the restriction could be lifted if a rock solid >>>> reason could be found, but as of yet, I haven't seen it. >>>> >>> >>> I don't believe there is any noticeable performance difference between >>> checking for nil and checking if a value is identical? to some sentinel >>> value (which would presumably be static, final, immutable and hence very >>> well optimised by the JVM). In addition, not allowing nils just means you >>> have to do extra work to wrap/unwrap nils as a user - which is almost >>> certainly a net loss on overall performance. >>> >>> Still, I think consistency is more significant than the performance >>> argument in this case. >>> >>> >>>> >>>> Timothy Baldridge >>>> >>>> >>>> On Tue, Aug 27, 2013 at 2:12 AM, Max Penet <m...@qbits.cc> wrote: >>>> >>>>> It's a real problem for me too, I also wonder what was the intention >>>>> behind this. I guess there could be a very good reason for this special >>>>> treatement of nils, but I haven't seen it yet. >>>>> >>>>> I would love to hear about this from people involved in core.async >>>>> development. >>>>> >>>>> On Friday, August 16, 2013 4:44:48 AM UTC+2, Mikera wrote: >>>>>> >>>>>> Hi all, >>>>>> >>>>>> I'm experimenting with core.async. Most of it is exceptionally good, >>>>>> but bit I'm finding it *very* inconvenient that nil can't be sent over >>>>>> channels. In particular, you can't pipe arbitrary Clojure sequences >>>>>> through >>>>>> channels (since sequences can contain nils). >>>>>> >>>>>> I see this as a pretty big design flaw given the ubiquity of >>>>>> sequences in Clojure code - it appears to imply that you can't easily >>>>>> compose channels with generic sequence-handling code without some pretty >>>>>> ugly special-case handling. >>>>>> >>>>>> Am I missing something? Is this a real problem for others too? >>>>>> >>>>>> If it is a design flaw, can it be fixed before the API gets locked >>>>>> down? >>>>>> >>>>> -- >>>>> -- >>>>> 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. >>>>> >>>> >>>> >>>> >>>> -- >>>> “One of the main causes of the fall of the Roman Empire was >>>> that–lacking zero–they had no way to indicate successful termination of >>>> their C programs.” >>>> (Robert Firth) >>>> >>>> -- >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To post to this group, send email to clojure@googlegroups.com >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> To unsubscribe from this group, send email to >>>> clojure+unsubscr...@googlegroups.com >>>> For more options, visit this group at >>>> http://groups.google.com/group/clojure?hl=en >>>> --- >>>> You received this message because you are subscribed to a topic in the >>>> Google Groups "Clojure" group. >>>> To unsubscribe from this topic, visit >>>> https://groups.google.com/d/topic/clojure/pF9FEP7b77U/unsubscribe. >>>> To unsubscribe from this group and all its topics, 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. >>> >> >> >> >> -- >> “One of the main causes of the fall of the Roman Empire was that–lacking >> zero–they had no way to indicate successful termination of their C >> programs.” >> (Robert Firth) >> >> -- >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to a topic in the >> Google Groups "Clojure" group. >> To unsubscribe from this topic, visit >> https://groups.google.com/d/topic/clojure/pF9FEP7b77U/unsubscribe. >> To unsubscribe from this group and all its topics, 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. > -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- -- 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.