The other day on IRC `mitsuhiko` (who I believe is actually Armin, the OP
in this thread) wrote that he would like to be able to write something like

    fn my_pipeline<I: Iterator<T>>(x: I) -> Iterator<T> { ... }

and that got stuck in my head: maybe it's not such a crazy idea. The
objections to having type inference at the API level seem sound to me:
besides implementation difficulty, if an inferred return type can
potentially be a local or anonymous type from the body of the `fn`, how are
you supposed to know, from the outside, what you can *do* with that type? I
don't really like `decltype` solution either: it solves a problem, but
working with it everywhere is just painful, and it ties the exposed
interface too closely to the implementation. If you specify a trait, these
problems are solved: it's still an unknown type from the body of the `fn`,
but now the interface you are allowed to use with it is clear. This is what
traits are for in the first place. There's still the big question of what
this syntax would actually *mean*, however, and there are some things, like
the actual representation (incl. size and alignment) of the type, which
still wouldn't be determined by the function signature, and would depend on
the body of the function, and I don't know how problematic that is. I think
this also might be intimately related to the DST/SST discussion, because
it's basically an unboxed existential.

Speaking of which: I completely agree with Patrick that there's no point to
blocking Rust 1.0 on backwards compatible features. The reason I'm
nonetheless wary of a drive to finalize the language too soon is that there
are still some really huge things outstanding, such as DST/SST, that we
still need to figure out, let alone implement, and ideally after
implementation there should also be a cooling-off period to see if
everything's working well, and that there aren't further issues that end up
getting raised as a consequence (or if there are, how to address them), and
so forth.


On Tue, Dec 31, 2013 at 3:52 PM, Huon Wilson <dbau...@gmail.com> wrote:

> On 01/01/14 01:43, Patrick Walton wrote:
>
>> On 12/31/13 6:09 AM, Huon Wilson wrote:
>>
>>> On 01/01/14 00:55, Armin Ronacher wrote:
>>>
>>>> Hi,
>>>>
>>>> On 30/12/2013 17:29, Patrick Walton wrote:
>>>>
>>>>> This is the first time I've heard of this as a missing feature, and I'm
>>>>> opposed. This would make typechecking significantly more complex.
>>>>>
>>>> I'm not saying someone should add decltype :)  Just that from using
>>>> the iterators we have now it becomes quite obvious that there are
>>>> missing tools to use them to the fullest extend.
>>>>
>>>
>> The question in my mind is whether all these things that we want are
>> backwards compatible, not whether they're nice to have. Anything backwards
>> compatible that is not already in the language is probably post-1.0 at this
>> point. *This is not because we don't want to add new features*—it's OK to
>> add new features to the language. Version 1.0 doesn't mean we are done and
>> the language is frozen for all time. It just means we're going to stop
>> making breaking language changes.
>>
>>  If we were to have unboxed closures similar to C++, where each closure
>>> is an (implicit) unique type, we'd likely need something like decltype
>>> (well, decltype(auto)) to make it possible to return them and things
>>> containing them, e.g. higher-order iterators like .map and .filter.
>>>
>>> (cc https://github.com/mozilla/rust/issues/3228 and
>>> https://github.com/mozilla/rust/issues/10448)
>>>
>>
>> Returning unboxed closures doesn't strike me as all that useful at the
>> moment, unless we add back capture clauses to allow values to be moved in.
>> Otherwise all you can refer to as upvars are passed-in parameters (due to
>> lifetime restrictions).
>>
>> In the event that you want to return closures that move in values, I
>> would say just use an explicit struct and a trait for now. We can revisit
>> this decision backwards compatibly if we need to in the future.
>>
>> Returning an iterator containing an unboxed closure that was passed in
>> doesn't require that feature, I don't think:
>>
>>     pub fn map<T,F:Fn<T>>(x: &[T], f: F) -> MapIterator<F> { ... }
>>
>
> I mean
>
>     fn my_pipeline<I: Iterator<T>>(x: I) -> MapIterator<FilterIterator<I,
> what_do_I_write_for_the_function_type_here>, and_again> {
>          x.filter(|un| boxed).map(|also| unboxed)
>     }
>
> (where the function/closure is the second param to {Map,Filter}Iterator.)
>
> Huon
>
>
>> Patrick
>>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to