On Apr 29, 2010, at 4:21 AM, ataggart wrote:
I know it won't matter, but for posterity if nothing else...
Functions named contains-key? and contains-val? would make a lot more
sense to me than the current contains? and new seq-contains?. Anyone
looking at contains-val? should expect it to be O(n). The only
effective difference would be that the test value for contains-val? is
consistently a single value rather than a [key value] tuple for maps.
I disagree.
People don't consider sets, vectors, arrays or strings to have 'keys'.
But, like maps, they all support fast lookup of some sort.
Would contains-val? be fast for sets? As a user of sets, I consider
them collections of values, and I absolutely would reach for contains-
val? in any library that had it, for use with sets. If so, and I used
contains-val?, and I moved code from using sets to maps (happens
frequently), or vectors (also happens) my perf would suddenly stink.
If not fast on sets, why not? The reason isn't supported by the name.
The mismatch with the seq values of maps is also disconcerting for
something that would purport to be sequential, as the things returned
by (seq amap) are key+value pairs.
Just because you wouldn't reach for contains? for use with a known
vector doesn't mean your code, or other code built on the abstraction,
won't end up calling it with a vector. And don't think you never use
contains? on a vector/array - you rewrite it every time you write (if
(and (<= 0 i) (< i (count v))) ...)
'contains?' and 'get' abstract over fast lookup. They are polymorphic
on the collection type and on the nature of the looked-up thing. For
maps the looked-up thing is a key, for sets: a value, for vectors,
strings and arrays: an index. Calling it contains-key? doesn't make
them the same, nor add any value.
In Clojure, 'contains?' is about 'get' succeeding. Nothing more or
less. It is not a rummager.
(if (contains? coll x)
(get coll x)
(plan-b))
Renaming contains? is not on the table. For people that understand its
relationship with get, it makes perfect sense (and I don't think I'm
the only one :). And there is a lot of client code. And no one has
come up with a better name that doesn't include caveats. contains? is
internally consistent, is unfamiliar.
I do understand that this use of the word differs from that used in
e.g., Java. But I'll make the same argument to Java devs that I do to
the Lispers, who have seen many more of their prized words repurposed
in Clojure (assoc, loop, do et al):
The words can't mean the same thing forever without trapping us
in the same semantics forever, and there are only so many good words.
Everyone has to realize that this level of polymorphism in Clojure is
unusual. I haven't seen a library with equivalents to get and
contains?. Heck, in Java, Maps aren't even collections! So, should we
adopt their nomenclature because it is familiar?
I agree that contains?'s behavior on vectors is confusing for
newcomers. That's not a reason for it to be different. And that people
need a way to do that rummaging job. They of course can, with 'some'.
But I also agree that 'some', being a higher-order function, would not
necessarily be the tool newcomers would consider for the job of
rummaging for a value. Perhaps it's a good first lesson, as they are
not going to find filter-val etc either.
So, I pulled in 'includes?' from contrib and renamed it seq-contains?
The only options for right now are:
A) I remove seq-contains?
B) I rename seq-contains?
I'm inclined towards A so we can all stop wasting time and energy on
this unnecessary function.
Rich
--
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