On Friday, September 9, 2016 at 11:36:22 AM UTC-5, Alan Thompson wrote:
>
> Hi Colin,
>
> I too have been bitten by this type of inconsistency in clojure.core 
> functions. 
>

I disagree that the problem here is consistency. The core functions are 
very consistent, but I think it's easy to build an insufficiently detailed 
mental model of what should happen when you're not aware of the distinction 
between collection functions (take and return data structures - things like 
conj, merge, assoc, get) and sequence functions (take and return sequences 
or really seq-ables - map, filter, etc).
 

> The root of the problem is that conj has different behavior for lists and 
> vectors, and that a seq behaves like a list. When map, filter, etc convert 
> the source vector into a seq, the behavior of conj changes accordingly.
>

In my opinion, the root of the problem is not being aware enough of when 
you move from working with data structures (like vectors) into working with 
sequence abstractions. Becoming more aware of the distinction and when 
those transitions occur is one of the more subtle aspects of learning 
Clojure.

I wrote this not too long ago on a very similar question on reddit:

https://www.reddit.com/r/Clojure/comments/4ve288/conj_i_just_dont_get_it_can_someone_help_me/

In order to avoid this kind of unpredictability, 
>

Just to belabor it, everything here is totally predictable already.
 

> you may wish to explore some of the functions to the Tupelo library. The 
> goal is to make things simpler, more obvious & predictable, and as 
> bulletproof as possible. One example is the append function.  Here is a 
> sample program comparing conj and append:
>
> (ns clj.core
>   (:require [tupelo.core :as t] ))
> (t/refer-tupelo)
>
> (def v [1 2 3])
>
> (conj v 4)                                  => [1 2 3 4]
> (conj (map identity v) 4)                   => (4 1 2 3)
> (conj (remove (constantly false) v) 4)      => (4 1 2 3)
> (conj (filter identity v) 4)                => (4 1 2 3)
>
>
As I wrote in the link above, I don't ever write code like this. When 
working with data in terms of seqs (map,remove,filter) you should be 
thinking in aggregates not in terms of individual values. Calling conj 
around a sequence is taking you from level of abstraction down into a lower 
level. This never comes up when I write Clojure (not exaggerating for 
effect, it just doesn't). 

I can't suggest an alternative here because the example is too narrow. 
Occasionally (much less now that we have transducers) I will have data in a 
seq and want to put it in a collection - into, vec, set are all sufficient 
to do so. Usually I find that either I can just leave it as a seq and 
continue OR that I can back up and make a collection instead of a seq in 
the first place (by using transducers, into, etc).
 

> (t/append v 4)                              => [1 2 3 4]
> (t/append (map identity v) 4)               => [1 2 3 4]
> (t/append (remove (constantly false) v) 4)  => [1 2 3 4]
> (t/append (filter identity v) 4)            => [1 2 3 4]
>
>
>
I disagree with everything about this. :) In my opinion you are working 
against Clojure's strengths in going down this path.
 

> I think simpler and more bulletproof functions can go a long toward making 
> Clojure easier to use, especially for beginners or when you are uncertain 
> about the exact type of a parameter.
>

I think more work on understanding the collection and sequence layers would 
pay far greater dividends than what you are suggesting.

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to