title: 'get' replacement that throws exception on not found?
body: <p>I'd like to access values in maps and records, throwing an exception when the key isn't present.  Here's what I've tried.  Is there a better strategy?</p>
  
  <p>This doesn't work because <code>throw</code> is evaluated every time:</p>
  
  <pre><code>(defn get-or-throw-1 [rec key]
    (get rec key (throw (Exception. "No value."))))
  </code></pre>
  
  <p>Maybe there's a simple method using a macro?  Well, this isn't it; it has same problem as the first definition, even if the evaluation of <code>throw</code> happens later:</p>
  
  <pre><code>(defmacro get-or-throw-2 [rec key]
    `(get ~rec ~key (throw (Exception. "No value."))))
  </code></pre>
  
  <p>This one works by letting <code>get</code> return a value that (in theory) would never be generated any other way:</p>
  
  <pre><code>(defn get-or-throw-3 [rec key]
    (let [not-found-thing :i_WoUlD_nEvEr_NaMe_SoMe_ThInG_tHiS_021138465079313
          value (get rec key not-found-thing)]
      (if (= value not-found-thing)
          (throw (Exception. "No value."))
          value)))
  </code></pre>
  
  <p>I don't like having to guess what keywords or symbols would never occur through other processes. (I could use <code>gensym</code> to generate the special value of <code>not-found-thing</code>, but I don't see why that would be better.  I don't have to worry about someone intentionally trying to defeat the purpose of the function by using the value of not-found-thing in a map or record.)</p>
  
  <p>Any suggestions?</p>