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.

Reply via email to