Clojure tends to blur the lines between its different types of collections 
and sequences, because of how most functions often know how to work with 
all of them and others will coerce them automatically from one type to 
another. This makes it that 99% of the time, everything just works like 
magic, but 1% of the time, you can be surprised and its important to 
understand that and learn how to recognize and debug those situations. The 
error message: "Don't know how to create X from Y" almost always indicates 
that you are in such a situation.

In your case, you have to realize that the function `first` works over all 
types that implement `ISeq` 
(https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java).
 
But if you look at its documentation: "Returns the first item in the 
collection. Calls seq on its argument. If coll is nil, returns nil." You 
can see that it will coerce the input to a ISeq automatically by calling 
the coercing function `seq` on it. Now `seq` can coerce a lot of things to 
an ISeq, but not Transient collections. That's why it throws the error 
"Don't know how to create ISeq from Transient".

The literal #{} constructs a new instance of PersistentHashSet. This type 
of data-structure does not implement ISeq, but can be coerced to an ISeq by 
`seq`. When you call `transient` on a PersistentHashSet though, you are 
coercing it to a TransientHashSet, and that type can not be coerced to a 
ISeq using `seq`.

So while Clojure doesn't have static types, it still has types, and its 
important to start recognizing and thinking in terms of them if you want to 
master Clojure.

I like to use the functions: `type`, `supers`, `bases` to help inspect what 
type I'm dealing with, and what interface they support. Then I resort to 
`doc` and `source` to see if the documentation mentions any form of 
implicit coercion, or if the source shows me which interface it'll actually 
use. Finally, some core functions delegate to Java for their 
implementation, so I sometimes go on github and look at the Java source to 
see what types they work with, such as 
: 
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L524

Hope this helps.
Didier

On Saturday, 24 February 2018 07:15:02 UTC-8, Alan Forrester wrote:
>
> Calling (first #{1}) gives the result 1. 
>
> Calling (first (transient #{1})) gives an error: 
>
> “IllegalArgumentException Don't know how to create ISeq from: 
> clojure.lang.PersistentHashSet$TransientHashSet  clojure.lang.RT.seqFrom 
> (RT.java:550)” 
>
> Is this behaviour intended? 
>
> And whether or not this is intentional is there a way round it? 
>
> Alan Forrester 
>
>
>

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