On 2 February 2010 00:18, Meikel Brandmeyer <m...@kotka.de> wrote:
> Consider this (admittedly constructed) case:
> (get-in {:a {:b 1}} [:x :c] {:c :uhoh})

Excellent point!


> Or to use butlast/last instead of peek/pop.

I think this is the best approach. butlast/last have linear time so
the overhead is small.

There are still some sharp edges I'm not sure about:
(A) user=> (get-in {:a 1} [])
{:a 1}
;; this is existing behavior, but I feel the result should be nil

(B) user=> (get-in {:a 1} nil)
{:a 1}
;; this is existing behavior, but I feel the result should be nil (nil
is a seq so not an exception)

(C) user=> (get-in {:a 1} 5)
java.lang.IllegalArgumentException: Don't know how to create ISeq
from: java.lang.Integer (NO_SOURCE_FILE:0)
;; existing behavior, seems sensible to throw an exception here rather
than return nil

(D) user=> (get-in {nil {:a 1}} [] 2)
{:a 1}
;; new behavior
;; using last/butlast only -> this is wrong... need to check the seq size
;; the solution depends upon what is correct for the preceding cases
so need to establish those first

Alternatively one could take the view that [] and nil are illegal key
sequences, in which case should get-in enforce that (via preconditions
or just a check) or should it just be added to the doc-string that
using those values is undefined, or both?

I've marked the ticket back to new in the meantime... will update once resolved.


For reference here is a version that behaves most like existing get-in:

(defn get-in
  "Returns the value in a nested associative structure,
  where ks is a sequence of keys. Returns nil if the key is not present,
  or the not-found value if supplied."
  ([m ks]
   (reduce get m ks))
  ([m ks not-found]
   (if (empty? ks)
     m
     (if-let [l (reduce get m (butlast ks))]
       (get l (last ks) not-found)
       not-found))))

I'm not convinced returning the map when given an empty key sequence
is the right thing to do, I'd prefer it to return nil or throw an
exception in both arity cases.


Regards,
Tim.

-- 
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

Reply via email to