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

Parameterising BuilderFactory by Coll rather than This

4 replies
DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.

Hi,

I'd like to be able to make it so that companions only have to define
an implicit builder rather than an implicit BuilderFactory and then
the implicit BuilderFactory would depend on the implicit Builder.
Unfortunately this runs into kindedness issues with the current
approach: The implicit builderToBuilderFactory method needs a number
of type parameters equal to the kindedness of the corresponding
collection (note: I'm finding that the way companions work is already
dealing quite badly with this. Is there anything that can be done to
fix that?)

One solution is that we have this Coll type in TraversableTemplate
which is always a normal type (e.g for List it's List[_]). Would it be
possible to parameterise BuilderFactory by that instead, or is there
something I'm missing that makes that not work properly? That way we
can define the implicit in Companion as

def builderToBuilderFactory(implicit builder : Builder[T, CC[T]) :
BuilderFactory[Coll, T, CC[T]] = ...

Adriaan Moors
Joined: 2009-04-03,
User offline. Last seen 42 years 45 weeks ago.
Re: Parameterising BuilderFactory by Coll rather than This
Hi,
I'd like to help out, but I'm having trouble understanding your email. Could you elaborate please?
cheers,adriaan

On Mon, Jun 15, 2009 at 1:20 PM, David MacIver <david.maciver@gmail.com> wrote:
Hi,

I'd like to be able to make it so that companions only have to define
an implicit builder rather than an implicit BuilderFactory and then
the implicit BuilderFactory would depend on the implicit Builder.
Unfortunately this runs into kindedness issues with the current
approach: The implicit builderToBuilderFactory method needs a number
of type parameters equal to the kindedness of the corresponding
collection (note: I'm finding that the way companions work is already
dealing quite badly with this. Is there anything that can be done to
fix that?)

One solution is that we have this Coll type in TraversableTemplate
which is always a normal type (e.g for List it's List[_]). Would it be
possible to parameterise BuilderFactory by that instead, or is there
something I'm missing that makes that not work properly? That way we
can define the implicit in Companion as

def builderToBuilderFactory(implicit builder : Builder[T, CC[T]) :
BuilderFactory[Coll, T, CC[T]] = ...


Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Parameterising BuilderFactory by Coll rather than This

ok. So there are two things, Builder and BuilderFactory.

Builder's have type

Builder[-From, +To];

BuilderFactories have type

BuilderFactory[This, -From, +To]

The purpose of a BuilderFactory is purely to supply builders. Under
the new scheme I'm working on for how they're constructed, Builders
are reusable so given a Builder[From, To] you can always get a
BuilderFactory[T, From, To] for any T. Therefore for a given T we
should be able to define

implicit def builderToBuilderFactory[From, To](implicit builder :
Builder[From, To]) = BuilderFactory[T, From, To](builder)

The problem is determining what T to use.

Currently the way builder factories are used approximates the
following (this isn't how the code actually works, but it conveys the
idea better than the actual code):

trait Traversable[+A]{
type This <: Traversable[A];

def map[B, R](f : A => B)(implicit bf : BuilderFactory[This, B, R]) : R = ...
}

I am proposing that the way it should work instead is

trait Traversable[+A]{
type Coll <: Traversable[_];

def map[B, R](f : A => B)(implicit bf : BuilderFactory[Coll, B, R]) : R = ...
}

The motivation for this is that otherwise sometimes
builderToBuilderFactory would need type parameters and sometimes it
wouldn't as the kindedness of the corresponding collection varies,
which makes it difficult to define it once in the Companion trait and
then have all collections inherit the correct behaviour for free.

2009/6/15 Adriaan Moors :
> Hi,
> I'd like to help out, but I'm having trouble understanding your email. Could
> you elaborate please?
> cheers,
> adriaan
>
> On Mon, Jun 15, 2009 at 1:20 PM, David MacIver
> wrote:
>>
>> Hi,
>>
>> I'd like to be able to make it so that companions only have to define
>> an implicit builder rather than an implicit BuilderFactory and then
>> the implicit BuilderFactory would depend on the implicit Builder.
>> Unfortunately this runs into kindedness issues with the current
>> approach: The implicit builderToBuilderFactory method needs a number
>> of type parameters equal to the kindedness of the corresponding
>> collection (note: I'm finding that the way companions work is already
>> dealing quite badly with this. Is there anything that can be done to
>> fix that?)
>>
>> One solution is that we have this Coll type in TraversableTemplate
>> which is always a normal type (e.g for List it's List[_]). Would it be
>> possible to parameterise BuilderFactory by that instead, or is there
>> something I'm missing that makes that not work properly? That way we
>> can define the implicit in Companion as
>>
>> def builderToBuilderFactory(implicit builder : Builder[T, CC[T]) :
>> BuilderFactory[Coll, T, CC[T]] = ...
>>
>>
>> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
>
>

Adriaan Moors
Joined: 2009-04-03,
User offline. Last seen 42 years 45 weeks ago.
Re: Parameterising BuilderFactory by Coll rather than This
Sorry, I still don't understand. I would say This and Coll both have kind * in your example, so what would change in BuilderFactory?   
(To be exact, This has kind *(Nothing, Traversable[A]), and Coll has kind *(Nothing, Traversable[X] forSome {type X}), where the kind *(L, U) classifies the proper types that are a subtype of U and a supertype of L)
 Also, wouldn't type inference be able to infer the T (assuming it's added to the list of type arguments of the method) that's unknown in the call to builderToBuilderFactory, based on the expected type of the BuilderFactory?
cheers,adriaan

On Mon, Jun 15, 2009 at 1:59 PM, David MacIver <david.maciver@gmail.com> wrote:
ok. So there are two things, Builder and BuilderFactory.

Builder's have type

Builder[-From, +To];

BuilderFactories have type

BuilderFactory[This, -From, +To]

The purpose of a BuilderFactory is purely to supply builders. Under
the new scheme I'm working on for how they're constructed, Builders
are reusable so given a Builder[From, To] you can always get a
BuilderFactory[T, From, To] for any T. Therefore for a given T we
should be able to define

implicit def builderToBuilderFactory[From, To](implicit builder :
Builder[From, To]) = BuilderFactory[T, From, To](builder)

The problem is determining what T to use.

Currently the way builder factories are used approximates the
following (this isn't how the code actually works, but it conveys the
idea better than the actual code):

trait Traversable[+A]{
 type This <: Traversable[A];

 def map[B, R](f : A => B)(implicit bf : BuilderFactory[This, B, R]) : R = ...
}

I am proposing that the way it should work instead is

trait Traversable[+A]{
 type Coll <: Traversable[_];

 def map[B, R](f : A => B)(implicit bf : BuilderFactory[Coll, B, R]) : R = ...
}

The motivation for this is that otherwise sometimes
builderToBuilderFactory would need type parameters and sometimes it
wouldn't as the kindedness of the corresponding collection varies,
which makes it difficult to define it once in the Companion trait and
then have all collections inherit the correct behaviour for free.

2009/6/15 Adriaan Moors <adriaan.moors@cs.kuleuven.be>:
> Hi,
> I'd like to help out, but I'm having trouble understanding your email. Could
> you elaborate please?
> cheers,
> adriaan
>
> On Mon, Jun 15, 2009 at 1:20 PM, David MacIver <david.maciver@gmail.com>
> wrote:
>>
>> Hi,
>>
>> I'd like to be able to make it so that companions only have to define
>> an implicit builder rather than an implicit BuilderFactory and then
>> the implicit BuilderFactory would depend on the implicit Builder.
>> Unfortunately this runs into kindedness issues with the current
>> approach: The implicit builderToBuilderFactory method needs a number
>> of type parameters equal to the kindedness of the corresponding
>> collection (note: I'm finding that the way companions work is already
>> dealing quite badly with this. Is there anything that can be done to
>> fix that?)
>>
>> One solution is that we have this Coll type in TraversableTemplate
>> which is always a normal type (e.g for List it's List[_]). Would it be
>> possible to parameterise BuilderFactory by that instead, or is there
>> something I'm missing that makes that not work properly? That way we
>> can define the implicit in Companion as
>>
>> def builderToBuilderFactory(implicit builder : Builder[T, CC[T]) :
>> BuilderFactory[Coll, T, CC[T]] = ...
>>
>>
>> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
>
>


Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Parameterising BuilderFactory by Coll rather than This

The problem isn't the kindedness of This vs. Coll. The problem is the
kind of the collection type.

The companion object needs to define a method that can create all
BuilderFactories of the right type. The problem is that in the current
implementation "the right type" has a number of type parameters which
depends on the kindedness of the collection.

So if I had something like

class DoubleVector { }

then BuilderFactory would have type

implicit def builderToFactory[T](builder : Builder[T, DoubleVector]) :
BuilderFactory[DoubleVector, T, DoubleVector] = ...

whereas with

class List[T]{}

it has to have type

implicit def builderToFactory[S, T](builder : Builder[T, List[T]]) :
BuilderFactory[List[S], T, List[T]] = ...

so the number of type parameters on builderToBuilderFactory is a
function of the kindedness of the collection.

In the version where instead we had

implicit def builderToFactory[T](builder : Builder[T, List[T]]) :
BuilderFactory[List[_], T, List[T]] = ...

it would not be.

2009/6/15 Adriaan Moors :
> Sorry, I still don't understand. I would say This and Coll both have kind *
> in your example, so what would change in BuilderFactory?
> (To be exact, This has kind *(Nothing, Traversable[A]), and Coll has kind
> *(Nothing, Traversable[X] forSome {type X}), where the kind *(L, U)
> classifies the proper types that are a subtype of U and a supertype of L)
>
> Also, wouldn't type inference be able to infer the T (assuming it's added to
> the list of type arguments of the method) that's unknown in the call
> to builderToBuilderFactory, based on the expected type of the
> BuilderFactory?
> cheers,
> adriaan
>
> On Mon, Jun 15, 2009 at 1:59 PM, David MacIver
> wrote:
>>
>> ok. So there are two things, Builder and BuilderFactory.
>>
>> Builder's have type
>>
>> Builder[-From, +To];
>>
>> BuilderFactories have type
>>
>> BuilderFactory[This, -From, +To]
>>
>> The purpose of a BuilderFactory is purely to supply builders. Under
>> the new scheme I'm working on for how they're constructed, Builders
>> are reusable so given a Builder[From, To] you can always get a
>> BuilderFactory[T, From, To] for any T. Therefore for a given T we
>> should be able to define
>>
>> implicit def builderToBuilderFactory[From, To](implicit builder :
>> Builder[From, To]) = BuilderFactory[T, From, To](builder)
>>
>> The problem is determining what T to use.
>>
>> Currently the way builder factories are used approximates the
>> following (this isn't how the code actually works, but it conveys the
>> idea better than the actual code):
>>
>> trait Traversable[+A]{
>>  type This <: Traversable[A];
>>
>>  def map[B, R](f : A => B)(implicit bf : BuilderFactory[This, B, R]) : R =
>> ...
>> }
>>
>> I am proposing that the way it should work instead is
>>
>> trait Traversable[+A]{
>>  type Coll <: Traversable[_];
>>
>>  def map[B, R](f : A => B)(implicit bf : BuilderFactory[Coll, B, R]) : R =
>> ...
>> }
>>
>> The motivation for this is that otherwise sometimes
>> builderToBuilderFactory would need type parameters and sometimes it
>> wouldn't as the kindedness of the corresponding collection varies,
>> which makes it difficult to define it once in the Companion trait and
>> then have all collections inherit the correct behaviour for free.
>>
>> 2009/6/15 Adriaan Moors :
>> > Hi,
>> > I'd like to help out, but I'm having trouble understanding your email.
>> > Could
>> > you elaborate please?
>> > cheers,
>> > adriaan
>> >
>> > On Mon, Jun 15, 2009 at 1:20 PM, David MacIver
>> > wrote:
>> >>
>> >> Hi,
>> >>
>> >> I'd like to be able to make it so that companions only have to define
>> >> an implicit builder rather than an implicit BuilderFactory and then
>> >> the implicit BuilderFactory would depend on the implicit Builder.
>> >> Unfortunately this runs into kindedness issues with the current
>> >> approach: The implicit builderToBuilderFactory method needs a number
>> >> of type parameters equal to the kindedness of the corresponding
>> >> collection (note: I'm finding that the way companions work is already
>> >> dealing quite badly with this. Is there anything that can be done to
>> >> fix that?)
>> >>
>> >> One solution is that we have this Coll type in TraversableTemplate
>> >> which is always a normal type (e.g for List it's List[_]). Would it be
>> >> possible to parameterise BuilderFactory by that instead, or is there
>> >> something I'm missing that makes that not work properly? That way we
>> >> can define the implicit in Companion as
>> >>
>> >> def builderToBuilderFactory(implicit builder : Builder[T, CC[T]) :
>> >> BuilderFactory[Coll, T, CC[T]] = ...
>> >>
>> >>
>> >> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
>> >
>> >
>>
>>
>> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
>
>

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