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

Reply via email to