- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Set.fill, Map.fill
Wed, 2011-12-14, 13:59
hi,
anyone know the reason why `fill` and `tabulate` are not defined for the companion objects of `Set` and `Map`?
val r = new util.Random()
List.fill(4)( r.nextInt( 10 )) // ok
IndexedSeq.fill(4)( r.nextInt( 10 )) // ok
Seq.fill(4)( r.nextInt( 10 )) // ok
Set.fill(4)( r.nextInt( 10 )) // not possible
Seq.fill(4)( r.nextInt( 10 )).toSet // stupid work around
Map.fill(4)( (r.nextInt( 25 ) + 65).toChar.toString -> r.nextInt( 10 )) // not possible
Seq.fill(4)( (r.nextInt( 25 ) + 65).toChar.toString -> r.nextInt( 10 )).toMap // stupid workaround
i can't think of a reason why it shouldn't be there?
best, -sciss-
Thu, 2011-12-15, 06:01
#2
Re: Set.fill, Map.fill
Generally, one expects C.fill(n)(...) to give you a collection of length n. This is not true for set and map.
You can always Iterator.fill(n){...}.toSet.
--Rex
On Wed, Dec 14, 2011 at 7:58 AM, Sciss <contact@sciss.de> wrote:
You can always Iterator.fill(n){...}.toSet.
--Rex
On Wed, Dec 14, 2011 at 7:58 AM, Sciss <contact@sciss.de> wrote:
hi,
anyone know the reason why `fill` and `tabulate` are not defined for the companion objects of `Set` and `Map`?
val r = new util.Random()
List.fill(4)( r.nextInt( 10 )) // ok
IndexedSeq.fill(4)( r.nextInt( 10 )) // ok
Seq.fill(4)( r.nextInt( 10 )) // ok
Set.fill(4)( r.nextInt( 10 )) // not possible
Seq.fill(4)( r.nextInt( 10 )).toSet // stupid work around
Map.fill(4)( (r.nextInt( 25 ) + 65).toChar.toString -> r.nextInt( 10 )) // not possible
Seq.fill(4)( (r.nextInt( 25 ) + 65).toChar.toString -> r.nextInt( 10 )).toMap // stupid workaround
i can't think of a reason why it shouldn't be there?
best, -sciss-
Thu, 2011-12-15, 12:01
#3
Re: Set.fill, Map.fill
Hi Rex,
> Generally, one expects C.fill(n)(...) to give you a collection of length
> n. This is not true for set and map.
maybe that was the reason to leave "fill" out in case of Set/Map. But
imo it would do no harm at all.
Using the same operator/method on different classes will often have
slight semantic differences. For instance, let's take List.apply and
Set.apply (or ++). Obviously, List.apply will add all elements of the
argument while the same is not always true for Set.apply. Are you
telling that they should be named differently for this reason:)?
In my view, the essence of "fill" is to allow the computation of
elements a nr of times; not to ensure that the collection has the same
size as the number of computations was. Set/Map users know about it,
anyway.
Further, if I extend Set and have a "fill" factory method with the
same signature and semantic, is that name no more a good choice?
Peter
Thu, 2011-12-15, 16:41
#4
Re: Re: Set.fill, Map.fill
On Thu, Dec 15, 2011 at 5:49 AM, Sonnenschein <peter.empen@arcor.de> wrote:
I similarly object to ++. I would use | instead, if it were defined on more than just pairs of sets, and would remove ++ from Set entirely.
For apply, no; the special case is worthwhile for the sake of convenience.
I would call that "repeat", not "fill".
If I were mixing sets and non-sets a lot, I would not name it fill.
It's not an entirely bad choice; it's just that these sorts of methods invite errors. Very often if you're trying to add items to a set, if they overlap it is actually an error on your part and/or in the data, _not_ an intentional trick used to reduce the size of the data. For example,
val dependents = employees.flatMap(_.familyNames)
if (dependents contains name) payBenefits(name, lookupEmployee(name))
has a huge chance of being wrong if employees is a set, since there may be colliding names of family members.
Sets are riddled with these sorts of dangers, but adding more does not particularly strike me as the right way to go.
--Rex
Hi Rex,
> Generally, one expects C.fill(n)(...) to give you a collection of length
> n. This is not true for set and map.
maybe that was the reason to leave "fill" out in case of Set/Map. But
imo it would do no harm at all.
Using the same operator/method on different classes will often have
slight semantic differences. For instance, let's take List.apply and
Set.apply (or ++).
I similarly object to ++. I would use | instead, if it were defined on more than just pairs of sets, and would remove ++ from Set entirely.
Obviously, List.apply will add all elements of the
argument while the same is not always true for Set.apply. Are you
telling that they should be named differently for this reason:)?
For apply, no; the special case is worthwhile for the sake of convenience.
In my view, the essence of "fill" is to allow the computation of
elements a nr of times
I would call that "repeat", not "fill".
Further, if I extend Set and have a "fill" factory method with the
same signature and semantic, is that name no more a good choice?
If I were mixing sets and non-sets a lot, I would not name it fill.
It's not an entirely bad choice; it's just that these sorts of methods invite errors. Very often if you're trying to add items to a set, if they overlap it is actually an error on your part and/or in the data, _not_ an intentional trick used to reduce the size of the data. For example,
val dependents = employees.flatMap(_.familyNames)
if (dependents contains name) payBenefits(name, lookupEmployee(name))
has a huge chance of being wrong if employees is a set, since there may be colliding names of family members.
Sets are riddled with these sorts of dangers, but adding more does not particularly strike me as the right way to go.
--Rex
Me too, was wondering about this some time ago. I cannot imagine a
real con.
Peter