A very good question. There's a fine, but ultimately irrelevant, reason for why I coded it that way originally, but I agree it's not quite right.
(1) Change the way present? works, and require a find-it-form instead of a WebElement object. This does a double-check for "existence" and "visibility," at the cost of changing the way the function is called.
(2) Remove any explicit check for "existence" in present? and make it another alias for visible?. This changes part of the intent of the function, but accomplishes the same goal (at this point in clj-webdriver's life) and does not change how present? is called.
The reason that exists? even needs to take a find-it form (instead of an object or record) is that clj-webdriver drops down to WebDriver directly when instantiating WebElement objects. This means that, if a find-it query fails to find an object, WebDriver itself throws an exception; that's why exists? uses the try/catch block with find-it.
As a result, this makes the current implementation of present? superfluous, because if an element doesn't exist, the exception will be thrown before present? is ever called, which is the behavior you're seeing.
If at some point I introduce a pure Clojure layer of abstraction over WebElements, then it will be possible to delay the actual instantiation of WebElement objects and we can write exists? like all the other functions that work on elements; by taking an element as its parameter. Until then, I'd like not to leak any more macros of this kind (that take find-it forms instead of WebElement objects) into the API, so I think I'll make present? an alias for visible?. The exists? function is a compromise of the current design, one that has not yet justified adding any more layers of abstraction to the rest of clj-webdriver.
Thanks for pointing this out! If anyone doesn't agree with the above, I'm game for further discussion.
-Daniel