We can have:

user=> {(+ 1 2) 1 (+ 2 1) 2}
IllegalArgumentException Duplicate key: 3  
clojure.lang.PersistentArrayMap.createWithCheck 
(PersistentArrayMap.java:71)


So clearly a check is also made *after* evaluating the key forms. I'm just 
not sure why we need to check *before* evaluating the key forms.


On Wednesday, January 4, 2017 at 9:16:26 PM UTC-8, tbc++ wrote:
>
> The check is made at read-time, by the time to form gets to the compiler 
> it's already a hash-map and one of your forms will have been dropped. So 
> the decision was made to make the reader check. One way you could solve 
> your problem here is with tagged literals, as the literal would be created, 
> and therefore the UUID would be unique before you even got to the creation 
> of the hash-map.
>
> http://clojure.org/reference/reader#_tagged_literals
>
> In short though...what should the reader do, it has no clue which of your 
> two key/value pairs to drop.  
>
> On Wed, Jan 4, 2017 at 9:05 PM, Tianxiang Xiong <tianxia...@gmail.com 
> <javascript:>> wrote:
>
>> Using a Clojure 1.8.0 REPL, I get the following:
>>
>> user=> {(+ 1 2) 1 (+ 1 2) 2}
>> IllegalArgumentException Duplicate key: (+ 1 2)  clojure.lang.
>> PersistentArrayMap.createWithCheck (PersistentArrayMap.java:71)
>>
>> It seems that the a check for key equality is made *before* the key is 
>> evaluated, when they are still strings.
>>
>> PersistentArrayMap/createWithCheck is as below:
>>
>> static public PersistentArrayMap createWithCheck(Object[] init){
>> for(int i=0;i< init.length;i += 2)
>> {
>> for(int j=i+2;j<init.length;j += 2)
>> {
>> if(equalKey(init[i],init[j]))
>> throw new IllegalArgumentException("Duplicate key: " + init[i]);
>> }
>> }
>> return new PersistentArrayMap(init);
>> }
>>
>> The MapReader in LispReader.java seems to pass an Object[] of Strings to 
>> PersistentArrayMap/createWithCheck.
>>
>> public static class MapReader extends AFn{
>> public Object invoke(Object reader, Object leftparen, Object opts, Object 
>> pendingForms) {
>> PushbackReader r = (PushbackReader) reader;
>> Object[] a = readDelimitedList('}', r, true, opts, 
>> ensurePending(pendingForms)).toArray();
>> if((a.length & 1) == 1)
>> throw Util.runtimeException("Map literal must contain an even number of 
>> forms");
>> return RT.map(a);
>> }
>>
>> }
>>
>>
>> This behavior is surprising. Is there a reason the map creation process 
>> works this way?
>>
>> The above example may seem trivial, since we would have duplicate keys 
>> after evaluation as well, but consider the generation of random values:
>>
>> user=> {(java.util.UUID/randomUUID) 1 (java.util.UUID/randomUUID) 2}
>> IllegalArgumentException Duplicate key: (java.util.UUID/randomUUID) 
>>  clojure.lang.PersistentArrayMap.createWithCheck 
>> (PersistentArrayMap.java:71)
>>
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> <javascript:>
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com <javascript:>
>> 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+u...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> “One of the main causes of the fall of the Roman Empire was that–lacking 
> zero–they had no way to indicate successful termination of their C 
> programs.”
> (Robert Firth) 
>

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