Stream: wg-traits

Topic: GAT use-case analysis


Aaron Turon (Mar 06 2019 at 21:08, on Zulip):

@centril you ready to chat?

centril (Mar 06 2019 at 21:09, on Zulip):

Sure; should we use hangouts? would be more effective

Aaron Turon (Mar 06 2019 at 21:10, on Zulip):

hm, i was hoping we could do it here to provide a more clear log / room for other people to jump in

centril (Mar 06 2019 at 21:10, on Zulip):

@Aaron Turon ah; ummh.. well I was thinking a paper doc + hangouts; we link to it here so people can dump stuff

Aaron Turon (Mar 06 2019 at 21:10, on Zulip):

(i will be ready in just a minute)

Aaron Turon (Mar 06 2019 at 21:13, on Zulip):

@centril https://paper.dropbox.com/doc/GAT-use-cases--AY1Ck74Fgk1Ztq1kHrethI8BAg-xFJQMxHXTOUekCyweukU1

centril (Mar 06 2019 at 21:14, on Zulip):

@Aaron Turon If you don't mind; I would prefer to also talk things through through voice

Aaron Turon (Mar 06 2019 at 21:14, on Zulip):

ok

Aaron Turon (Mar 06 2019 at 21:14, on Zulip):

lemme grab a room

centril (Mar 06 2019 at 21:15, on Zulip):

@Aaron Turon https://meet.google.com/hxa-pjpd-uvx ?

Aaron Turon (Mar 06 2019 at 21:15, on Zulip):

yep i'm there now

Aaron Turon (Mar 06 2019 at 21:43, on Zulip):

@nikomatsakis ok, we've generated a small set of some representative examples and analysis: https://paper.dropbox.com/doc/GAT-use-case-analysis--AY1Ck74Fgk1Ztq1kHrethI8BAg-xFJQMxHXTOUekCyweukU1

Aaron Turon (Mar 06 2019 at 21:44, on Zulip):

TLDR we can get quite a lot of benefit from lifetime/type abstraction without any bounds at all

Aaron Turon (Mar 06 2019 at 21:44, on Zulip):

this is perhaps most vital for abstracting over async functions that borrow

Aaron Turon (Mar 06 2019 at 22:10, on Zulip):

@Taylor Cramer i bet you have other good GAT examples to add -- particularly interested in things that are relatively "urgent" since this is partly feeding into prioritization

Taylor Cramer (Mar 06 2019 at 23:01, on Zulip):

ooh ooh

Taylor Cramer (Mar 06 2019 at 23:01, on Zulip):

so many things :)

Taylor Cramer (Mar 06 2019 at 23:01, on Zulip):

@Aaron Turon are you primarily asking about lifetime ones, or do type ones count as well?

varkor (Mar 06 2019 at 23:02, on Zulip):

types are surely just as important

centril (Mar 06 2019 at 23:11, on Zulip):

@Taylor Cramer everything and anything ;) The distinction between "has bound" and not is probably more important wrt. chalk vs. rustc than types vs. lifetimes

Taylor Cramer (Mar 06 2019 at 23:22, on Zulip):

Ah, so you're looking for examples that have bounds?

Taylor Cramer (Mar 06 2019 at 23:22, on Zulip):

Bounds on the parameters of the associated type itself is very unclear to me since I've never been sure what parts of that are inferred from WF requirements

Taylor Cramer (Mar 06 2019 at 23:23, on Zulip):

do you mean bounds that wouldn't be included in WF requirements?

centril (Mar 06 2019 at 23:24, on Zulip):

@Taylor Cramer well use cases of GATs in general; just dump them in the doc and then we can segregate based on type/lifetime and bound-on-assoc-type/bound-on-parameters-of-assoc-type/no-bounds

centril (Mar 06 2019 at 23:25, on Zulip):

iirc bounds on the parameters of an associated type need to be satisfies when the associated type is used as opposed to those on an associated type itself (which are really just constraints on the trait)

centril (Mar 06 2019 at 23:26, on Zulip):

(the Haskell equivalent is probably clearer in this respect)

varkor (Mar 06 2019 at 23:26, on Zulip):

for the Functor example, you could plausibly want type Out<B>: Functor<B>;, which is a nontrivial bound

varkor (Mar 06 2019 at 23:26, on Zulip):

or are we talking bounds on the type parameter?

centril (Mar 06 2019 at 23:26, on Zulip):

@varkor I think it's useful without it as well; you accept more things that maybe you shouldn't

centril (Mar 06 2019 at 23:27, on Zulip):

@varkor it's unclear really; Niko knows better what sort of bounds need chalk and which dont

varkor (Mar 06 2019 at 23:27, on Zulip):

(I'm not sure I would actually enforce it in a real API, but for "generating use cases", it's a potential example)

centril (Mar 06 2019 at 23:28, on Zulip):

@varkor ah; well -- use cases with emphasis on real world practicality ;)

varkor (Mar 06 2019 at 23:29, on Zulip):

that's what I'm saying: it's a reasonable bound to have

varkor (Mar 06 2019 at 23:30, on Zulip):

oh, in my current draft of Functor, I do have this bound

varkor (Mar 06 2019 at 23:30, on Zulip):

so I think it is a realistic example :)

centril (Mar 06 2019 at 23:31, on Zulip):

Right; that's probably true, but I think you can get away without it also so it might not be all we want in the end but the initial version may not require chalk

centril (Mar 06 2019 at 23:31, on Zulip):

(so we can maybe ship sooner)

varkor (Mar 06 2019 at 23:34, on Zulip):

yeah, it's definitely not one that is absolutely dependent on bounds

nikomatsakis (Mar 08 2019 at 21:40, on Zulip):

@Aaron Turon @centril nice, I've not had time to look at the examples yet, I'll try to schedule some time for that on Monday.

centril (Mar 08 2019 at 21:41, on Zulip):

@nikomatsakis feel free to add your own :slight_smile:

Aaron Turon (Mar 08 2019 at 21:47, on Zulip):

@nikomatsakis no worries -- fwiw i think this list could be a lot longer (cc @Taylor Cramer) but i think we already have enough to answer the basic questions around what benefits we could get from the most basic form of GATs

Taylor Cramer (Mar 08 2019 at 21:51, on Zulip):

Yup, I have it on my list to fill this out more

Taylor Cramer (Mar 08 2019 at 21:51, on Zulip):

Sorry I haven't had a chance to do that yet @Aaron Turon

Aaron Turon (Mar 08 2019 at 21:51, on Zulip):

@Taylor Cramer no worries, and no rush!

Aaron Turon (Mar 08 2019 at 21:51, on Zulip):

we have what we need for now, i think, and otherwise this is just a catalog that could be helpful for answering futures design/impl questions

centril (Mar 08 2019 at 21:56, on Zulip):

@Aaron Turon and also test cases!

scalexm (Mar 09 2019 at 19:49, on Zulip):

@centril @Aaron Turon I believe you would need an additional bound on the StreamingIterator example

scalexm (Mar 09 2019 at 19:50, on Zulip):

something along the lines of:

trait StreamingIterator {
    type Item<'a> where Self: 'a;

   // there already is some sort of implicit `where Self: 'a` here because of `&'a mut self`
   fn next<'a>(&'a mut self) -> Self::Item<'a>;
}
scalexm (Mar 09 2019 at 19:51, on Zulip):

otherwise, you cannot do:

impl<T> StreamingIterator for Foo<T> {
    type Item<'a> = &'a T; // error: `T` does not outlive `'a`, hence `&'a T` is not well-formed
}
scalexm (Mar 09 2019 at 19:52, on Zulip):

whereas with the were Self: 'a, it means that you can project <SomeType<...> as StreamingIterator>::Item<'a> only if SomeType<...>: 'a

scalexm (Mar 09 2019 at 19:53, on Zulip):

but on the assoc type value you can now rely on Self: 'a, which in my example is Foo<T>: 'a which would imply the needed T: 'a

scalexm (Mar 09 2019 at 19:54, on Zulip):

hence this invalidates your sentence:

Most of our examples don’t use any bounds at all; those that do tend to bound the associated type itself, not its parameter

here, I'm bounding the Self parameter

scalexm (Mar 09 2019 at 19:57, on Zulip):

regarding whether chalk is needed or not, I don't think chalk is actually really needed, it's just that we have already modeled in chalk things like what bounds should be relied on vs what bounds you should be proving and when, and all this stuff naturally translates into logical rules which the engine can solve

Matthew Jasper (Mar 09 2019 at 19:57, on Zulip):

The functor example also has a B: Sized bound

scalexm (Mar 09 2019 at 19:57, on Zulip):

so you don't need to think too much about the implementation details

scalexm (Mar 09 2019 at 19:58, on Zulip):

@Matthew Jasper yes totally, although you'll have implicit Sized bounds on parameters as soon as you allow generic type parameters

Matthew Jasper (Mar 09 2019 at 20:00, on Zulip):

Well, you could require that ?Sized is always used. But that seems unlikely to be a version that we want stabilized.

scalexm (Mar 09 2019 at 20:01, on Zulip):

@centril @Aaron Turon also I believe chalk has more "first-class" support for quantification over types (although I've already added some support for that in rustc within the chalk integration work), but again it is not needed if we want to target something quickly shippable which would e.g. only have generic lifetimes

Taylor Cramer (Mar 10 2019 at 07:38, on Zulip):

@Aaron Turon commented on the doc -- perhaps this belongs more in the lang chat, but I realized I didn't remember discussing the syntax for specifying required GATs in bounds-- a la Box<dyn Iterator<Item = u8>> today, would you have Box<dyn for<'a> StreamingIterator<Item<'a> = &'a u8>>?

Taylor Cramer (Mar 10 2019 at 07:45, on Zulip):

or, given the above, Box<dyn for<'a> where(Self: 'a) StreamingIterator<Item<'a> = &'a u8>>

Taylor Cramer (Mar 10 2019 at 07:45, on Zulip):

ick ick ick

scalexm (Mar 10 2019 at 09:54, on Zulip):

@Taylor Cramer I think the only way for this bound to be valid would be through Box<dyn for<‘a> StreamingIterator<Item<‘a> = &’a u8> + ‘static>

scalexm (Mar 10 2019 at 10:00, on Zulip):

But this seems restrictive, since you’re going to call next() only with short lifetimes

scalexm (Mar 10 2019 at 10:02, on Zulip):

I think we might be able to just not need specifying the where bounds so that Box<dyn for<‘a> StreamingIterator<Item<‘a> = &’a u8>> just works (even in the presence of a where Self: ‘a bound in the trait decl)

scalexm (Mar 10 2019 at 10:03, on Zulip):

Proving the where Self: ‘a bound is only important when projecting, e.g. naming (dyn for<‘a> StreamingIterator<Item<‘a> = &’a u8>)::Item<‘lifetime> with a concrete ’lifetime

centril (Mar 10 2019 at 10:03, on Zulip):

The ability to specify where on for<...> binders is useful tho and we should think of ways to introduce it

scalexm (Mar 10 2019 at 10:04, on Zulip):

@centril that’s right but probably out of scope for an initial GATs implementation

centril (Mar 10 2019 at 10:04, on Zulip):

probably

Last update: Nov 18 2019 at 01:45UTC