darcs patch: add Data.Set.notMember and Data.Map.notMember

Thu Mar 9 11:18:06 PST 2006 John Meacham

Hello,
Maybe I missed something, but are these two worth a name?
For reference:
notMember k m = not $ member k m,
in pointless style:
notMember = (not .) . member
Any evidence to add to the case ?
Cheers,
JP.
On 3/9/06, John Meacham
Thu Mar 9 11:18:06 PST 2006 John Meacham
* add Data.Set.notMember and Data.Map.notMember _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On Thu, Mar 09, 2006 at 11:09:50PM +0100, Jean-Philippe Bernardy wrote:
Hello,
Maybe I missed something, but are these two worth a name?
For reference: notMember k m = not $ member k m, in pointless style: notMember = (not .) . member
Any evidence to add to the case ?
* symmetry with elem/notElem * quite useful for cleaning up guards: f x | not (x `Set.member` map) && foo = ... is hard to read. * only a single obvious interpretation of meaning so people likely to define their own with same name conflicting with each other and it won't hurt to provide them. * I likes em. John -- John Meacham - ⑆repetae.net⑆john⑈

John Meacham wrote:
On Thu, Mar 09, 2006 at 11:09:50PM +0100, Jean-Philippe Bernardy wrote: [...]
Any evidence to add to the case ?
* symmetry with elem/notElem
I don't like notElem either
* quite useful for cleaning up guards:
f x | not (x `Set.member` map) && foo = ... is hard to read.
You may swap quards (or the "then" and "else" branches of "if"), or avoid the infix notation (which is horrible in this case anyway). I don't think we need negated versions of any boolean function, that's what "not" is for! Christian

Christian Maeder wrote:
I don't think we need negated versions of any boolean function, that's what "not" is for!
seconded. -- -- Johannes Waldmann -- Tel/Fax (0341) 3076 6479/80 -- ---- http://www.imn.htwk-leipzig.de/~waldmann/ -------

Since everyone is disagreeing, and I think these are a good idea, I thought I'd just say so.
only a single obvious interpretation of meaning so people likely to define their own with same name conflicting with each other and it won't hurt to provide them. This is the killer reason
If "not" is so easy and simple, why do we have both break and span ;) Thanks Neil

If "not" is so easy and simple, why do we have both break and span ;)
OK, drop break. I mean, ( not . take ) break. Or something like that. "In anything at all, perfection is finally attained, not when there is no longer anything to add, but when there is no longer anything to take away..." Antoine de Saint-Exupery, Wind, Sand and Stars -- -- Johannes Waldmann -- Tel/Fax (0341) 3076 6479/80 -- ---- http://www.imn.htwk-leipzig.de/~waldmann/ -------

Johannes Waldmann wrote:
If "not" is so easy and simple, why do we have both break and span ;)
OK, drop break. I mean, ( not . take ) break. Or something like that.
"In anything at all, perfection is finally attained, not when there is no longer anything to add, but when there is no longer anything to take away..." Antoine de Saint-Exupery, Wind, Sand and Stars
For newbies like me, being a bit more verbose over being terse is the same thing as making things easier and faster to learn etc. The second problem is that where do you draw the line? If you have a small working set of basic primitives, you can build everything on top of them separately: there is no need for libraries at all... :) Which reminds me of the language called Dyalog APL: it was delivered with a set of "programming idioms" (say 1000 or something), shorter and longer one-liners that can do nice things on matrices etc but as a user, I should copy them to my own code or to design my own library based on them. (And this is fustrating.) I wonder, why they don't provide a library or several libraries containing those idioms as helper functions. That does not do any harm while I consider the habit of copying the same idiom several times a bad habit. If there is a need to change it, it means more work over doing a change in one place (by e.g. overriding the usual lib definition by reading the function from some other lib etc). And if there is a need to go over every line, it is still easier to change a name to another than a programming construct. br Isto

On Friday 10 March 2006 12:32, Christian Maeder wrote:
John Meacham wrote:
On Thu, Mar 09, 2006 at 11:09:50PM +0100, Jean-Philippe Bernardy wrote: f x | not (x `Set.member` map) && foo = ... is hard to read.
You may swap quards (or the "then" and "else" branches of "if"), or avoid the infix notation (which is horrible in this case anyway).
What makes you think so (referring to the 'horrible' part)? Ben

Hello Christian, Friday, March 10, 2006, 2:32:02 PM, you wrote:
f x | not (x `Set.member` map) && foo = ... is hard to read.
btw, (x `not.Set.member` map), as proposed by Doaitse Swierstra, will look better in this case -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Bulat Ziganshin wrote:
Hello Christian,
Friday, March 10, 2006, 2:32:02 PM, you wrote:
f x | not (x `Set.member` map) && foo = ... is hard to read.
btw, (x `not.Set.member` map), as proposed by Doaitse Swierstra, will look better in this case
This does not type check, try: (not . elem) 1 [1..2] C.

I don't like notElem either
* quite useful for cleaning up guards:
f x | not (x `Set.member` map) && foo = ... is hard to read.
You may swap quards (or the "then" and "else" branches of "if"), or avoid the infix notation (which is horrible in this case anyway).
Although I'd normally agree with negated versions of things being somewhat redundant, the infix version here is rather important, since one often wants the code to look the same way as the mathematics. The symbols \in and \not\in are both usually written infix, and that's not going to change soon. Putting the membership operation in between is nice, because we read the guard here as "If x is a member of xs then..." rather than "If member x xs then..." anyway. Perhaps if the proposal to allow somewhat more general expressions as infix operators goes through (which I'm actually ambivalent about), I'd feel different about this case. If you want to reduce redundancy, let's unify the 3 separate ways to say 'map'. :) - Cale

Cale Gibbard wrote:
I don't like notElem either
* quite useful for cleaning up guards:
f x | not (x `Set.member` map) && foo = ... is hard to read.
I think the plain application "not (Set.member x map) && foo" is more appropriate for a programming language like haskell with a somewhat limited support of mathematical notations (i.e. not postfix applications).
Although I'd normally agree with negated versions of things being somewhat redundant, the infix version here is rather important, since one often wants the code to look the same way as the mathematics. The symbols \in and \not\in are both usually written infix, and that's not going to change soon.
latex does not have to consider precedences and the latex sources also look much less nice than the final printed version. Christian

Christian Maeder wrote:
John Meacham wrote:
On Thu, Mar 09, 2006 at 11:09:50PM +0100, Jean-Philippe Bernardy wrote: [...]
Any evidence to add to the case ?
* symmetry with elem/notElem
I don't like notElem either
* quite useful for cleaning up guards:
f x | not (x `Set.member` map) && foo = ... is hard to read.
You may swap quards (or the "then" and "else" branches of "if"), or avoid the infix notation (which is horrible in this case anyway).
I don't think we need negated versions of any boolean function, that's what "not" is for!
Christian
Having notElem is needed for those of us who have a different opinion of using infix notation (which is big part of Haskell's syntactic sugar compared to Scheme). Adding to a library is a matter of balance: is there name clear or ambiguous? is it being added because it is wanted or speculatively? In this case there seems to be one clear meaning to the name "notElem" and there are users who actually want it. So "notElem" and "notMember" are both good things to put in the library. -- Chris
participants (10)
-
Benjamin Franksen
-
Bulat Ziganshin
-
Cale Gibbard
-
Chris Kuklewicz
-
Christian Maeder
-
Isto Aho
-
Jean-Philippe Bernardy
-
Johannes Waldmann
-
John Meacham
-
Neil Mitchell