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

Set.fill, Map.fill

4 replies
Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.

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-

Peter 2
Joined: 2011-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Set.fill, Map.fill

Me too, was wondering about this some time ago. I cannot imagine a
real con.
Peter

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
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:
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-


Peter 2
Joined: 2011-02-16,
User offline. Last seen 42 years 45 weeks ago.
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

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Re: Set.fill, Map.fill
On Thu, Dec 15, 2011 at 5:49 AM, Sonnenschein <peter.empen@arcor.de> wrote:
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

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