This page is no longer maintained — Please continue to the home page at www.scala-lang.org

what it means to contain something

7 replies
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.

Do people feel like this is the correct behavior? It has caught me out
enough times now that I've stopped using default map values, which is a
really annoying resolution because they're super handy. Especially if
the value type is a list or other collection and you'd like to have it
default to the empty one.

scala> Map[String, String]() withDefaultValue "bippy"
res0: scala.collection.immutable.Map[String,String] = Map()

scala> res0 contains "hi"
res1: Boolean = true

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: what it means to contain something

On Tue, Feb 8, 2011 at 8:14 PM, Paul Phillips wrote:
> Do people feel like this is the correct behavior? It has caught me out
> enough times now that I've stopped using default map values, which is a
> really annoying resolution because they're super handy.  Especially if the
> value type is a list or other collection and you'd like to have it default
> to the empty one.
>
> scala> Map[String, String]() withDefaultValue "bippy"
> res0: scala.collection.immutable.Map[String,String] = Map()
>
> scala> res0 contains "hi"
> res1: Boolean = true
>
contains is just get != None. That's a useful equivalence to have IMO.
If contains changes, does get need to change as well?

Cheers

Dan Shryock
Joined: 2010-01-07,
User offline. Last seen 42 years 45 weeks ago.
Re: what it means to contain something


On Tue, Feb 8, 2011 at 11:14 AM, Paul Phillips <paulp [at] improving [dot] org> wrote:
Do people feel like this is the correct behavior? It has caught me out enough times now that I've stopped using default map values, which is a really annoying resolution because they're super handy.  Especially if the value type is a list or other collection and you'd like to have it default to the empty one.

scala> Map[String, String]() withDefaultValue "bippy"
res0: scala.collection.immutable.Map[String,String] = Map()

scala> res0 contains "hi"
res1: Boolean = true


I thought there'd be a quick solution to just use keySet.contains instead of contains on the Map directly, but it also seems to have a very confusing behavior:
scala> val s = Set('a','b')s: scala.collection.immutable.Set[Char] = Set(a, b)
scala> s contains 'a'      res8: Boolean = true
scala> s contains 'c'      res9: Boolean = false
scala> val map = Map[String, String]() withDefaultValue "bippy"map: scala.collection.immutable.Map[String,String] = Map()
scala> map contains "hi"res10: Boolean = true
scala> map.keySetres11: scala.collection.Set[String] = Set()
scala> map.keySet contains "hi" res12: Boolean = true

Dan
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: what it means to contain something

On 2/8/11 11:57 AM, martin odersky wrote:
>
> contains is just get != None. That's a useful equivalence to have IMO.
> If contains changes, does get need to change as well?

Useful right up until the implementation for get is fixed at Some(_), at
which point contains is a constant function. It comes down to what
people use "contains" for. I personally would gladly abandon that
equivalence in favor of having "contains" mean "this key has been placed
in this map". I can see why others would choose otherwise. I don't
have the opinion that get inherently needs to move with it.

If I can't change contains then I could sure use a method which means
the above; containsIgnoringDefaultValues.

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: what it means to contain something
I'd say that I find the behavior surprising....  but this is under the assumption that withDefaultValue only does the following modification:
def apply(key : Key) : Value = get(key).getOrElse(defaultValue)
It seems I also need to start being more careful with default values and maps.

On Tue, Feb 8, 2011 at 2:57 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
On Tue, Feb 8, 2011 at 8:14 PM, Paul Phillips <paulp [at] improving [dot] org> wrote:
> Do people feel like this is the correct behavior? It has caught me out
> enough times now that I've stopped using default map values, which is a
> really annoying resolution because they're super handy.  Especially if the
> value type is a list or other collection and you'd like to have it default
> to the empty one.
>
> scala> Map[String, String]() withDefaultValue "bippy"
> res0: scala.collection.immutable.Map[String,String] = Map()
>
> scala> res0 contains "hi"
> res1: Boolean = true
>
contains is just get != None. That's a useful equivalence to have IMO.
If contains changes, does get need to change as well?

Cheers

Donna Malayeri
Joined: 2009-10-21,
User offline. Last seen 42 years 45 weeks ago.
Re: what it means to contain something
I would agree--how else can you know if the Map "really contains" that key?
Donna
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: what it means to contain something

On Tue, Feb 8, 2011 at 9:16 PM, Paul Phillips wrote:
> On 2/8/11 11:57 AM, martin odersky wrote:
>>
>> contains is just get != None. That's a useful equivalence to have IMO.
>> If contains changes, does get need to change as well?
>
> Useful right up until the implementation for get is fixed at Some(_), at
> which point contains is a constant function.  It comes down to what people
> use "contains" for.  I personally would gladly abandon that equivalence in
> favor of having "contains" mean "this key has been placed in this map".  I
> can see why others would choose otherwise.  I don't have the opinion that
> get inherently needs to move with it.
>
> If I can't change contains then I could sure use a method which means the
> above; containsIgnoringDefaultValues.

I am not saying we can't change contains, just that we cannot look at
it in isolation.
Any proposal has to look at all map methods, and how they play
together. That includes contains, get, and also keySet. There seems to
be an inconsistency that iterators over sets do not see default
elements but get's do. So maybe we should change that, in which case
we need to decide whether we should worry about backwards
compatibilities, or whether we consider the previous behavior a bug.

Cheers

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: what it means to contain something
On Tue, Feb 8, 2011 at 9:16 PM, Paul Phillips <paulp [at] improving [dot] org> wrote:
> On 2/8/11 11:57 AM, martin odersky wrote:
>>
>> contains is just get != None. That's a useful equivalence to have IMO.
>> If contains changes, does get need to change as well?
>
> Useful right up until the implementation for get is fixed at Some(_), at
> which point contains is a constant function.  It comes down to what people
> use "contains" for.  I personally would gladly abandon that equivalence in
> favor of having "contains" mean "this key has been placed in this map".  I
> can see why others would choose otherwise.  I don't have the opinion that
> get inherently needs to move with it.
>
> If I can't change contains then I could sure use a method which means the
> above; containsIgnoringDefaultValues.

I am not saying we can't change contains, just that we cannot look at
it in isolation.
Any proposal has to look at all map methods, and how they play
together. That includes contains, get, and also keySet. There seems to
be an inconsistency that iterators over sets do not see default
elements but get's do. So maybe we should change that, in which case
we need to decide whether we should worry about backwards
compatibilities, or whether we consider the previous behavior a bug.

Cheers

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland