or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing
xxxxxxxxxx
RTN syntax options
This doc lays out the RTN syntax options and some of the arguments for or against a particular choice.
There is one subtle point. The current decision is focused on a particular use case (bounding the return for all values of generic parameters and parameter types), but the choice also impacts what we might do for potential future use cases (e.g., bound the return type for specific values of generic parameters or parameter types; specifying which functions are const), so the examples given cover those use cases as well (and in some cases multiple possibilities). But it's important to realize that we are not deciding on those future use cases yet – there is still room to debate and/or find alternatives, and we may decide not to solve those problems at all.
Status quo:
T: Trait<method(): Send>
,T::method(): Send
As our baseline case, we will discuss the syntax that is currently (partially)[1] implemented, along with some of its strengths and weaknesses. This will also introduce a sample program that we can port to future syntaxes.
Given the following trait and top-level function…
One could write functions that bound the return type of the
items
method as follows:One could also use the RTN form as a type, e.g. for local variables.
<>
would be required to use this as part of a fully qualified function calls.Note that in this context,
D::items()
would instantiate the generic arguments of the method with inference variables not universal variables.Finally, although not currently being proposed, this proposal could be extended to cover future use cases:
Strong points
T: Database<items(): DoubleEndedIterator>
), this syntax is fairly short.Downsides or concerns that have been raised
Some of these points will be addressed by other proposals.
Some(..)
means "any number of arguments with any values".T::foo(): Send
notation means "prove for all possible values", which is a safe over-approximation (are there counterexamples?).T::items()
could mean "with all arguments" or "with no arguments".()
here is "kind of" sugar for::Output
, but this is a new kind of sugar that doesn't build on the intution of "accessing an associated type of something".<>
to use fully qualified functions.T::items()::next
would be ambiguous, so<T::items()>::next
is required. People may not be familiar with this form. We could also support turbofish likeT::items::()::next
.generate_items()
took no arguments and meant "the return type for some set of arguments".generate_items(0)
took arguments.generate_items()
"ought" to mean that no arguments have been given.write(): Send
makes the future Send and not the final result.()
as sugar for::Output
, at least conceptually, an associated typefoo: FnOnce
and a methodfoo
would shadow each other, and there would be no way to disambiguate.Dot-dot:
T::foo(..)
To address the concerns of inconsistency with pattern form, another option is to require
..
in the parentheses.Functions bounding return types:
As a type:
Finally, although not currently being proposed, this proposal could be extended to cover future use cases:
Strong points
Some(..)
means "any number of arguments with any values"...
"? –nikomatsakis)()
, this form remains fairly concise. It has more sigils but they are oriented at removing confusion so it will feel more obvious to some readers.Downsides or concerns that have been raised
Some of these points will be addressed by other proposals.
<>
to use fully qualified fuctions (as above).generate_items(..)
as a type vs an expression:..
is a legal expression; we could use...
instead, as that is not a legal expression, but (a) that feels inconsistent with patterns; (b) this is not obviously going to be an issue; and © it's unclear that...
would feel less confusing to users, e.g., nikomatsakis forgot that...
was not a valid expression until this point was raised.(..)
as sugar for::Output
, at least conceptually, an associated typefoo: FnOnce
and a methodfoo
would shadow each other, and there would be no way to disambiguate.Return:
T::foo::return
To address the confusion between
()
in expression position vs type, the syntax::return
has been proposed.Functions bounding return types:
As a type:
Future use cases not currently being proposed:
Strong points
<>
.D::items::return::next
.D::items_with_key<ItemKey>::return
.D::process_items(ItemProcessor)::return
.D::items::return
means "all arguments" andD::items()::return
would mean "no arguments".Downsides or concerns that have been raised
Some of these points will be addressed by other proposals.
D: Database<items::return: Send>
feels fairly "dense" and intimidating. The juxtaposition of::
and:
, while not new to Rust, is also unfortunate.::Output
.Output
to represent the return type in theFn*
traits. If we use::return
for RTN, it feels like it should work elsewhere also.::yields
.::return
as sugar for::Output
, at least conceptually, an associated typefoo: FnOnce
and a methodfoo
would shadow each other, and there would be no way to disambiguate.Higher-ranked-projections:
D::items::Output
To address the concern that prior proposals feel like a "new concept" (bounding return value of a function), it was proposed that we could write
D::items::Output
, referencing theOutput
associated type defined on theFnOnce
trait. The idea is to generalize the notationT::Foo: Bound
whereFoo
is an associated type from the traitSomeTrait
andfor<'a> T: SomeTrait<'a>
to meanfor<'a> <T as SomeTrait<'a>>::Foo: Bound
.As a type:
Future use cases not currently being proposed:
Strong points
T::Item
is illegal ifT
has a higher-ranked bound; this is a more useful semantics, but is it the right one?Downsides or concerns that have been raised
Output
on the future andOutput
on theFn
type.FnOnce
andFuture
.D: Database<items::Output: Send>
feels fairly "dense" and intimidating. The juxtaposition of::
and:
, while not new to Rust, is also unfortunate.D::process_items(ItemProcessor)::Output
.foo: FnOnce
and a methodfoo
would shadow each other, and there would be no way to disambiguate.Migration note
Even if we did ultimately adopt this idea, if we adopted any of the prior proposals, we could say that e.g.
()
or(..)
is just sugar for::Output
.Fn form:
T: Trait<fn method(): Send>
,fn T::method(): Send
An interesting alternative that arose in discussions about how best to handle
const
bounds was to use thefn
keyword as a prefix.Bounding return types:
As the type of local variables:
Future use cases:
An interesting twist that this permits is bounding the return type of an async function, though then the distinction between
fn request(): Send
(bounds the future) andasync fn request(): Send
(bounds the result of awaiting the future) is quite subtle.Strong points
const
bounds (not to overrotate on that).Downsides or concerns that have been raised
Some of these points will be addressed by other proposals.
~~~: ~~~~~
.fn T::items()
could mean "with all arguments" or "with no arguments".fn T::items(..)
to handle that.<>
to use fully qualified fuctions, doesn't compose into type chains very nicely.fn
"prefix" makes composing this into chains kind of visually ambiguous (though perhaps not ambiguous in a formal sense):fn T::items()::next(&mut iter)
as an expression orfn T::items()::Item
as a type.<>
was require to disambiguate:<fn T::items()>::next(&mut iter)
<fn T::items()>::Item
Evaluation and recommendation
Lang team members are required to give their thoughts on preferences.
Other readers are encouraged to do so as well, but please add your names/entries after the lang team member block.
Thanks!
Instructions:
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →The options in short
D: Database<items(): DoubleEndedIterator>
D: Database<items(..): DoubleEndedIterator>
D: Database<items::return: DoubleEndedIterator>
D: Database<items::Output: DoubleEndedIterator>
D: Database<fn items(): DoubleEndedIterator>
D: Database<fn items(..): DoubleEndedIterator>
D: Database<fn items::return: DoubleEndedIterator>
D: Database<fn items::Output: DoubleEndedIterator>
Big table
Put in
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →f()
f(..)
f::return
f::Output
fn f()
fn f(..)
fn f::return
fn f::Output
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →nikomatsakis
Ultimately, my top concern is that the syntax be relatively concise and unintimidating and easy to explain. I find that basically all the options involving parens meet that criteria. I am aware that I expect most uses to be using trait aliases most of the time, but I still think people will encounter the syntax, and I also expect some number of "one-off" bounds that show up internally where a trait alias feels like too much trouble.
I am torn between StatusQuo and DotDot. I prefer StatusQuo for the most part – typing a pair of parens is so pleasant, and it's so compact – but I cannot get past the "hunch" that we will regret it. Literally every time I explain it to someone, they feel it is inconsistent with pattern syntax. Even if that inconsistency is well justified, I don't relish explaining that for the rest of time. There is also the possibility of variadics, though I admit that weighs less heavily on me (we could for example use
..
in that case) – but I've also learned not to dismiss these kinds of forward-looking concerns, since often an inconsistency that seems small now feels larger when we start driving the future design forward. (One other thought:(..)
feels a bit more surprising if we never allow specifying the types of individual parameters; it strongly suggests you can put things in there. I'm not sure if we really want to go that way or not.)I am surprisingly intrigued by the Fn and FnDotDot options, though they seem kind of "out there". My biggest hesitation is that I have to think kind of hard to figure out where the
fn
keyword should go. It kind of reminds me of C's syntax for function pointer types: even though it's fairly logical, it's always a puzzle to writetypedef void (*foo)(u32)
or whatever the heck it is (did I get that right?). I would be interested in the idea of some kind of experiment of trying to write a module or two using it to see how it feels.I like the Output option as well, but for very different reasons. It does not feel "nice" to use, but it feels like a logical-ish extension of the current system. I am worried about how docs and other things will look when people encounter it in the wild, though, I think it's going to be dense and hard to visually parse. Overall I'd be interested in considering this extension in the future. That said, I would feel fine about
(..)
being a shorthand syntax for it. I am not sure how much to worry about the confusion betweenOutput
on theFuture
trait andOutput
on theFn
traits – it might be an issue, but that's already a kind of confusion (i.e., is this bounding the result of async fn or what) and I'm not sure how much worse it'll be.I have strong reservations about
::return
. Unlike::Output
, it doesn't feel like an extension of what we have, it feels like something new – it's a keyword and it refers to the return type of a method, but it is verbose and takes me time to read and think about. I would not hard block it if others were aligned around it of course.I am not too worried either way about specifying the values for generic parameters or the types of arguments, though I do expect it'll come up and I like having some options.
tmandry
My current top choice is
f()
because of this point:But I still can see why we would prefer
f(..)
and go back and forth on this point myself.Looking at the code examples makes me dislike
::return
and::Output
more, from the standpoint of sheer verbosity. I think we should strive to minimize the verbosity of writing Rust code where possible. I also dislike::return
because of how special (and out of place) it is, and::Output
because of its ambiguity withFuture
. If I could go back in time and renameFuture
's associated type I probably would, and then I would be neutral on::Output
.My concerns with
fn f()
are that it looks too much like function pointer syntax in type position. The line between "this represents a function" and "this represents the return type of a function" has become too thin.The only problem with this is that we might want a way to bound by
const
in the future. Maybe something like this can work:I don't understand why someone would combine the
fn
proposals with a projection, hence my hard blocking designation, though I'm willing to reconsider. It seems like it's mixing two concerns together. Perhaps we should have this as a means of namespace disambiguation, but I would not support it as the primary syntax for users.joshtriplett
Aside: in the future, can we please not use "status quo" for "current proposal"? The status quo is that we don't have a syntax for this.
What are the other places it should work? I expect that my answer would be "yes, it should work anywhere it makes sense" (any time you have a function type); for instance, if you have
F: FnOnce(u32) -> u64
,F::return
should work (and beu64
).In general, I feel like
::return
is extensible and orthogonal in a way I find elegant. However, I can already see people's feelings on it from the table, and while I'd like to understand that better, I'm not going to fight for it from a perspective of it being my top choice and most other people's last choice.I do think we should provide a way to get the type of the method itself, as well. I think this is another factor to consider here: extensibility.
method::return
goes naturally withmethod::arg
or similar, as well as withmethod::fn
to get the method type itself if you need to do that explicitly. (Though if you're already in type space it may make sense formethod
to juts be the function type.)I would like to better understand what it means for
::return
to be "dense". It is definitely noticeably longer than()
, and that is a downside. It doesn't seem semantically more complex, though, insofar as the concepts we're referencing (the name of the return type).I find the argument that
::Output
has the potential for confusion very compelling, to the point that I think that outweighs its advantages. I think::Output
is more strongly associated with Future than Fn traits, because you have to writeFuture<Output=...>
but we have syntactic sugar forFn(...) -> ...
.While I don't love having to use the turbofish syntax, I think it does fully address the concern I had about being able to specify argument types where needed. (And I don't think we should tie any of this to a new syntax for
impl Trait
arguments.) So, I'm going to drop that concern: I do agree that it's possible for most of these syntaxes, and not unique to::return
.For the same reason, I don't feel like
..
is a sufficient win over()
to be worth what feels like syntactic salt.Regarding the
()
syntax, I feel like it's the least bad option here, at this point. My only forward-compatibility concern is whether this will end up taking away options when in the future we have type-level functions (e.g. functions that return types and can be evaluated at compile time). Is there a way we can hedge about that.Note (1) in the table above: If
fn
is an optional disambiguator I would be- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →pnkfelix
I decided my top choice is
fn foo()
.The presence of the
fn
keyword in thefn foo(..)
andfn foo()
options is a good signal to the user that something interesting is going on. And (as noted in doc) it also provides a natural extension point for e.g.async fn
. So I'm pretty sure my green checkmark is going to go with one of those two options.I don't mind
fn foo(..)
at all, but if we can get away withfn foo()
, then I think it would be nice to avoid so much ceremony. (I.e. I can imagine people being annoyed by requiring both thefn
and the..
. (Unless we followed up quickly with features that justified the..
.) So that's why I put my- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →fn foo()
.I think
foo()
on its own is too subtle.foo(..)
restores the balance a bit there, so that I don't regard it as too subtle.As forafter reflection, I decided I don't dislike these that much, and have put them both on the samefoo::return
andfoo::Output
, I have decided I dislike them equally. I think thefoo::Output
option is potentially the most "natural" choice from the viewpoint of what pre-existing features exist in the language+stdlib…- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →foo()
for my row.scottmcm
TC
I agree with all points of nikomatsakis' analysis. On the points which he expressed feeling torn, I feel torn similarly. (Consider everything he said above incorporated here by reference.)
The one concern I would perhaps emphasize more strongly is that of ambiguity between type and value space. I.e.:
(Rust treats types and values (including functions) as occupying separate namespaces.)
While we could say that the
()
,(..)
, or::return
forms would not, strictly speaking, be ambiguous if they only worked with functions (and not types), this would break the mental model that these forms are "just sugar" for::Output
. To the degree that people would think of these as sugar for::Output
, these would carry the same risk of ambiguity. And this ambiguity could be a problem if we ever wanted to more literally make e.g.(..)
simple sugar for::Output
or we wanted to expose the type of the function itself.In terms of decisions we could make on the syntax about which we might later have regret, this seems a plausible candidate.
Here's a proposed design axiom:
Everywhere that our "most fully-qualified form" is not actually fully-qualified enough seems like a mistake in retrospect (c.f. having no way to refer to shadowed inherent methods on a trait object, which is question 10 on dtolnay's quiz).
Once we stabilize ATPIT (associated type position impl Trait), it will become more common to have associated types that implement the
Fn*
traits (trivially, because it will go from being impossible to being possible). So this ambiguity could begin to matter in new ways.While we could hope that naming conventions might save us here, there are reasonable use cases in macros for violating these convensions.
Similarly, one of the design axioms proposed in the recent RTN meeting was:
For this reason (and to not add any more questions to dtolnay's quiz), my preference is one of the
Trait<fn foo(..): Bound>
-style forms (or any alternate proposal that similarly distinguishes referencing these two namespaces). Ergonomically, I prefer eitherfn foo(..)
orfn foo()
. For the sake of consistency, I believe we should also supportfn foo::Output
and treat the(..)
or()
forms as sugar for this.However, overall, I'm in favor of RTN in any reasonable form, and I'll unreservedly support whatever consensus we align around.
Nadri
My two cents:
fn foo()
scans well, expecially in the middle of a complex type. It's unambiguous that we're talking about a function, so the meaning can be inferred from syntax. That feels crucial to me.I see the further possibilities like
async fn
/const fn
as a sign that this new concept has weight to it. I wasn't feeling that withfoo()
syntax.(..)
has the benefit of looking like a pattern, so would expect extensions likefn foo(_, SomeType, ..)
.fn foo()
feels like it's comitting to never allowing arguments later.Design meeting
Date: 2024-03-04
People: TC, nikomatsakis, tmandry, pnkfelix, Josh, CE, eholk, Nadri
Minutes/driver: TC
(Please write down your analysis above (and read the analyses of others) before filling in topics below.)
position of
fn
keyword in Fn formpnkfelix: The downsides section for Fn form references a few examples written like
<fn T::items()>::Item
. I am just curious: Is there an, um, "obvious" reason that this would not instead be written<T::fn items()>::Item
? (I'm not claiming that this change in position would do anything to address the listed downside regarding<~~~>
and such; I was just wondering about what seemed "natural" when I was reading the text, in terms of whether I would prefer to have thefn
near the function name, or as a much earlier prefix before we write the path at all.)nikomatsakis: Not really, I wanted to mirror the declaration syntax, and
::fn
"feels" dense to me (e.g.,Foo: Database<items::fn: Send>
).Josh: I also feel like combining a syntax involving a space with a syntax involving
::
feels like it creates a "grouping" that doesn't exist:T::fn items()
looks likeT::fn
followed byitems()
to me.Josh: That said, I personally like the idea of
items::fn
, for the same reason I liked::return
, but I think that would mean the function type, not the return type.(The meeting ended here.)
Only the "associated type bounds" form is currently implemented. ↩︎