When I first started learning Clojure 3.5 years ago I was "bit" by this in 
my first month or so of doing Clojure but after spending a little bit of 
time to understand how the sequence abstraction works it was never a 
problem again. I agree with everything that Alex says here. 

On Friday, September 9, 2016 at 10:04:44 AM UTC-7, Alex Miller wrote:
>
>
> 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