From: Chas Emerick <c...@cemerick.com>
Date: Sun, 5 Aug 2012 10:33:12 -0400
Local: Sun, Aug 5 2012 10:33 am
Subject: Re: Question about sets
On Aug 5, 2012, at 2:56 AM, Sean Corfield wrote:
> On Sat, Aug 4, 2012 at 11:45 PM, Mark Engelberg
I hit exactly the problem the OP raised this past week. I knew of the (good) restriction on e.g. #{1 1} being an error, and remember some of the conversations leading up to the changes that made it so, but had either forgotten or never quite internalized that #{a b} is also an error, where a and b are equivalent values.
> <mark.engelb...@gmail.com> wrote: >> In any case, Clojure is already able to detect when x and y are equal in >> something like #{x y} and report it as an error. > So do you think #{1 1} should not be an error? And {:a 1 :a 2}? These
First, some history:
=> (hash-set 1 2 2)
The only way to get around the checks here is to use `set` or `into`; note that there is no "constructor" function for an unsorted map that does not check that the provided keys are unique.
Interestingly, sorted maps and sets do *not* have the same restriction:
=> (sorted-map 1 2 1 3)
Quoting Rich from the mailing list thread linked above:
> These are bugs in user code. Map literals are in fact read as maps, so In the end, even though I've been recently "bitten" by the checked creation of sets from a literal, I think it's a reasonable approach. In #{a b}, you are specifying the creation of a set containing two and exactly two values, those named by a and b. There's an explicit invariant being specified in that code. Thinking over my various uses of #{} syntax, I remember times where I've expected it to enforce that invariant (and throw an error if dupes were provided) and times where I've expected it to implicitly apply `distinct` to the values provided; that indicates sloppiness on my part, not a place where the language should become psychic.
> a literal map with duplicate keys isn't going to produce an evaluated > map with distinct keys. If you create an array map with duplicate > keys, bad things will happen. In contrast, `set` and `into` each accept a seqable collection of data, and are explicit about their support for sifting out duplicates (right in the docstring of `set`, and transitively so for `into` due to its use of `conj` and its semantics on sets).
Finally, for the sake of consistency, it seems like the same checks should be applied by the sorted map and set "constructor" functions, and that there should be a map corollary to `set` (i.e. a function that is the equivalent of #(into {} %), just as `set` is the equivalent of #(into #{} %)). This last one is problematic in terms of naming, though.
Cheers,
- Chas
--
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
| ||||||||||||||