> I like Lisp in general but it frustrated me (before also with Common Lisp)
> that it seems Lispers often claim the language can help you fly higher while
> in reality it actually makes your walking more difficult. Even it can help
> you fly higher, that will still turn off many people because we walk much
> more than fly. And there is no REAL reason that you need to walk slower when
> trying to fly higher. All those nuances are self imposed without any true
> substantial reason.

Can you provide an example of this subseqx function in a different
language? The sequence abstraction is not unique to Clojure. C# has
the IEnumerable<T> abstraction, and Python has iterators. All of these
will cause the same problems you are expressing of changing the type.
That is, doing .Where(x => x == 1) on a List<int> in C# will return a
IEnumerable<int> at that point you haven't a clue what the concrete
type was originally.

To better explain my point, let's look at contains? Many people
(including myself) get confused about contains?. For instance:

=> (contains? [1 2 3] 1)
true
=> (contains? [2 3 4] 4)
false

What's going on here? Well contains is a key based look-up. [1 2 3]
has a 1st element so the that is true, but [2 3 4] does not have a 4th
element, so our second form evaluates to false. So what contains?
actually does is say "perform a constant-time lookup on the collection
to see if key exists". Since searching [2 3 4] for the number 4 is not
constant time, that is not the algorithm that is implemented.

Okay, so back to subseqx. The problem is that you are asking  for a
mixture of semantics. Is subseqx a constant time operation? On a
vector, yes. On a seq, no.

This is where the simplicity Clojure attempts to employ comes into
play. Don't write a function that sometimes takes O(1) and other times
takes O(log32) or O(n).

This also comes into play with the function conj. People mistakenly
think conj means "add this element to the end" or "add this element,
but do it differently depending on the collection". Instead what conj
really means is "add in the most efficient way possible". For lists
conj would then be like cons. For vectors conj adds on the end. For
maps, conj is the same as assoc (more or less).

So there you have it. Simplicity here is defined as stating that a
given function will always take the same time to perform the same
action, and that will not employ a bunch of if/then magic.

To answer your question then, since we are using different semantics
for each collection you should use:

drop/take - for seqs and lists
subvec - for vectors
select-keys - for maps

Hopefully this helps clear it up a bit.

Timothy

-- 
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