On Apr 28, 7:17 pm, Douglas Philips <d...@mac.com> wrote:
> On 2010 Apr 28, at 6:55 PM, Stuart Halloway wrote:
>
> > Specializations are available where there is a clear use case, e.g.
> > contains?, peek (instead of last), disj, etc.
> ...
> > Tying to concrete types is limiting. *Never* having special purpose
> > fns that know about performance characteristics is also limiting.
>
> > contains?/seq-contains? mark a divide where it is very easy for a
> > language to quietly help programmers do the wrong thing.
>
> Such as littering my application code with type-checks to decide if
it
> should call contains? or seq-contains?
> That seems exactly the wrong thing to do.
>
> Please explain how making seq-contains? fast for sets and maps is
> wrong (exactly how does it violate some contract and what contract,
> explicitly is that a violation of) and application code type checking
> is right, because I really don't understand why making seq-contains?
> fast isn't just a huge win-win.
>
It is an important aspect of Clojure that, in general, performance
guarantees are part of the semantics of functions. In particular,
functions are not supported on data structures where they are not
performant.
You can't just swap out sequences or lists for maps or sets in a
program. So, you need to use the right data structure for the job, and
then the right functions will be available. When it makes sense, some
functions are maximally polymorphic (e.g. seq, or into). But lookup,
under any name, shouldn't be, IMO, so it isn't in Clojure. Similarly
there is no insert at the beginning of vectors, append to end of
lists, lookup for values of maps, insertion in the middle of sequences
etc. I simply don't want to provide the tools for people to write
programs in Clojure with N^2 performance - that benefits no one. But
I've seen such performance degradation in many a Lisp program as
people build upon O(n) functions on lists.
If you have a lookup table in your program, please use a set or map,
or, if by index, a vector. You will have get, contains? or nth
available, performance will be good, and that will be clear from the
code.
seq-contains? exists because sometimes, say in a macro, you have a
known short sequence and need to test for the presence of something.
There's no need to copy it into a set. And people have been rolling
their own includes? etc for this job. Now everyone can use seq-
contains? for that. Its poor performance is indicated by its name and
documentation. Should someone try to take a piece of code based on seq-
contains? and try to scale it, they will see that function as an
obvious bottleneck.
Your type-check argument is a straw man that doesn't hold up in
Clojure practice. People tend to use the right data structures for the
job and don't choose algorithms via type checks.
Clojure is not particularly duck-type-y, in general things are not
unified by the presence of same-named functions but by underlying
shared abstractions. Just because protocols can be used to make things
reach many types doesn't mean they should be used to unify things that
aren't uniform.
If you want to get a feel for how the abstractions in Clojure are
organized, have a look at the slides in the middle of this
presentation (about 30 pages in):
http://clojure.googlegroups.com/web/tutorial.pdf
While you may not agree with it (and everyone disagrees with
contains? :), at least the design is a considered one.
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