In this specific case, I might personally use something like: (render-image (some-> product-image-list first deref))
...or maybe write a little function that does the above. Alternately, in (render-image) you might start out with (if (nil? cursor) (default-image) (code-to-render @cursor)). You'd need to check for nil to render the default image even if deref was nil-punnable, right? Tim On Monday, September 12, 2016 at 4:30:00 AM UTC-4, Deon Moolman wrote: > > Hi Tim, > > Thanks for your feedback, I appreciate it! :) > > Ye, I've been tempted and bitten by atoms-in-atoms before, and that's no > fun - My case here is slightly different though, I have a single atom and > construct cursors to paths within, which are swappable and deref'able like > normal atoms, but they modify the value of the original atom (just their > allocated slice inside though). > > I'll give a bit of detail on one very specific usecase I have, my > structure looks like so: > > My atom (and its value) looks like so: > > (atom > {:product > [{:product/id 1 :product/name "Cooker"} > {:product/id 2 :product/name "Pan"}] > :image > [{:image/id 1 :image/url "..." :image/product 1}]}) > > And I have a function (reverse-lookup) that will take a product id and > return a list of cursors that point to the individual images for a product, > so: > > (reverse-lookup :image/product 1) => [(cursor {:image/id :image/url "..." > :image/product 1})] > (reverse-lookup :image/product 2) => [] > > If I'm only interested in, say, rendering the first image, I can call > (render-image > @(first product-image-list)) - without nil-punning, I have to do add an > if to every usage, where I'd rather just handle nil to a default image > placeholder inside render-image. > > I also have a function will literally return the first (and likely only) > element in the lookup, which will also return a cursor or nil if not found. > One could argue that the data needs integrity checking in that case before > getting into the atom, but in my case I'd rather just nil-pun all the > things since it's not exactly a big deal. > > Anyhow - back to the original question - I'm wondering if there's anything > I'm missing about the decision to not nil-pun deref - If it's simply a > matter of 'didn't really think of it', that's fine, I'm quite content to > work around it, but if there's a deeper philosophical reason, then I'm keen > to add it to my understanding of the underlying foundation of clojure. > > Thanks again for all the feedback, I really do appreciate your time! > > Cheers, > - Deon > > On Sat, Sep 10, 2016 at 9:08 PM, Timothy Baldridge <tbald...@gmail.com > <javascript:>> wrote: > >> I've worked with a model much like this, and as an experience report: it >> resulted in a lot of pain. Atoms inside atoms, or really more than one atom >> for the entire state of your app results in to many sources of mutability. >> On top of that, you have the problem of async updates: some part of your >> state may or may not exist depending if some async call to the server has >> completed yet. I can't say much more without seeing your code, but I would >> use this as an opprotunity to re-think the design of the app a bit. >> >> If you are getting nils in unexpected places you can either nil-prune >> (what you're asking for here), or you can ask "why am I getting a nil here >> when I didn't expect it...how can I keep from doing this in the future?". >> Perhaps the answer is as simple as never calling the render function of a >> component until all its state exists (Om.Next takes an approach somewhat >> like this). >> >> On Sat, Sep 10, 2016 at 11:12 AM, Deon Moolman <cmdr...@gmail.com >> <javascript:>> wrote: >> >>> Hi Sean, >>> >>> Good point - as you have noticed, my use case is in ClojureScript - I'm >>> using reagent cursors (hence the deref) fairly heavily to chop my main atom >>> up and send only the relevant bits to components, but still allow them to >>> locally modify their state. >>> >>> In my specific case, I do lookups for parts of the tree that may not >>> exist, and in that case 'nil' is the obvious return value. >>> >>> Cheers, >>> - Deon >>> >>> On Fri, Sep 9, 2016 at 6:55 PM, Sean Corfield <se...@corfield.org >>> <javascript:>> wrote: >>> >>>> Like Stuart, I don’t encounter atom-or-nil as a common pattern – could >>>> you explain why you have functions that might return an atom or might >>>> return nil? >>>> >>>> >>>> >>>> FYI, We have about 40,000 lines of Clojure at World Singles and just a >>>> handful of atoms (and most of those are going away as we refactor the code >>>> to use Component more extensively). >>>> >>>> >>>> >>>> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN >>>> An Architect's View -- http://corfield.org/ >>>> >>>> "If you're not annoying somebody, you're not really alive." >>>> -- Margaret Atwood >>>> >>>> >>>> >>>> On 9/9/16, 1:10 AM, "Deon Moolman" <clo...@googlegroups.com >>>> <javascript:> on behalf of cmdr...@gmail.com <javascript:>> wrote: >>>> >>>> >>>> >>>> Hey all, >>>> >>>> >>>> >>>> I'm having some pain with atoms and dereferencing nil - mostly around >>>> my functions sometimes returning an atom and other times nil - I don't >>>> really want to create a special 'nil' atom and do the bits for returning >>>> that and I don't want to be checking nils absolutely everywhere when >>>> nil-punning works perfectly otherwise, so I was wondering what the >>>> pitfalls >>>> of this approach would be? >>>> >>>> >>>> >>>> (extend-type nil IDeref >>>> >>>> (-deref [_] nil)) >>>> >>>> >>>> >>>> Effectively, make @nil nil-pun to nil. makes sense to me? >>>> >>>> >>>> >>>> Cheers, >>>> >>>> - Deon >>>> >>>> >>>> >>>> >>>> >>>> -- >>>> 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 >>>> <javascript:> >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> To unsubscribe from this group, send email to >>>> clojure+u...@googlegroups.com <javascript:> >>>> 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/ot_sD2sJW0A/unsubscribe. >>>> To unsubscribe from this group and all its topics, send an email to >>>> clojure+u...@googlegroups.com <javascript:>. >>>> 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 clo...@googlegroups.com >>> <javascript:> >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+u...@googlegroups.com <javascript:> >>> 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+u...@googlegroups.com <javascript:>. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> >> >> -- >> “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 clo...@googlegroups.com >> <javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> 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/ot_sD2sJW0A/unsubscribe. >> To unsubscribe from this group and all its topics, send an email to >> clojure+u...@googlegroups.com <javascript:>. >> 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.