The goal was, from the point of view of a framework writer to give a self documenting method signature to the framework user to say "this block is optional and not escaping" while now optional is forced to be escaping (for obvious reasons). From memory management point of view, if the block is just used within the scope of the function then it will be released when the scope of the function is finished.
Without any doubt, we would be telling to who is using this function "hey, you don't need to weakly self here". At the moment this is something you can know just by knowing how the function is implemented when a block is optional, While it is Cristal clear when the closure is not optional.
I haven't read the comments in this thread yet so forgive me for that. I think I asked this @Slava_Pestov once, but I don't remember if it was here in the forums or on twitter. The issue from the original post is that @escaping is implicit in generic context. This is a little bit odd and if you don't know that it can lead to bugs in your code.
I'm also not sure if this would not be a significant source breaking change because the attribute was not required before. Also you can't really add it to Optional's initializer because Wrapped is not known to be a function type.
All optional closures must be escaping, since the closure is stored inside the Optional.some case.
One could argue that it might sometimes be beneficial to be able to mark such closures as non-escaping. However, that would require some kind of language support to mark Optional as escaping/nonescaping too, or somehow add some sort of compiler magic to infer wether or not the optional that is contaning the nonescaping closure will actually outlive the caller.
This seems very non-trivial to me, but what do I know?
However, short answer is: The closure must be escaping, so no need to explicitly mark it. The same goes for instance members, etc.
@GLanza I see. I probably read a little too fast, my bad .
I do like @glessard suggestion (and was about to suggest it myself if he hasn't).
To add on what others said, that it's non-trivial to add it; we don't want Optional to be special. Sure, it does have proliferated amount of sugar, but it usually ends up being normal enum with 2 cases. If we want non-escaping closure in Optional, we'd want to support it on everything else, say Foo. To make anything non-escaping, we'd need its container to be non-escaping as well, which means we want non-escaping variables.
There could definitely be a better way, but I think that's how we're likely gonna end up if we really want this feature.
Rather than putting the annotation on the Optional, @nonEscaping Optional<() -> ()>, it put it on the generic Type of the optional: Optional<@nonEscaping () -> ()>. I'm not sure how Functions are designed internally, but I would imagine that simplifies the implementation. Rather than allowing something to be added to an Optional-if-the-optional-is-a-function, just support it as a general annotation for functions.
There should be no source compatibility issues. It's an additive change that doesn't change any existing Types
If desired, supporting both @escaping and @nonEscaping to any function could be supported with no compatibility issues, and left up to the user what they want to make explicit.
How much would it cost to extend the idea of escaping to every input? To know that an option closure was non-escaping, you'd have to track the enum (Optional) input and then use knowledge that it wouldn't escape to conclude that the closure inside it doesn't.
Unless the unwrap operation is copying the variable internally, (which I don't know), Is there a reason the same rules can't be applied as a typical non-escaping parameter? Are the mechanisms I'm unaware of to indicate that a general parameter can't be copied? If not I can imagine that being something that could/should be added to the language generally.
The point is that I don't want to write an "empty" function for each block I might want to be optional, just for the sake of having a prettier method signature. I was wondering if it's possible and appreciated something synthesised by the compiler, and maybe even checkable like completion.isEmpty I have no idea if it's doable.
It should be quite straightforward to extend escape analysis to optional parameter functions and allow them to be explicitly marked as @escaping or @nonEscaping (or however we want to spell that). We can also investigate changing the default language rule for optional parameter functions so that it's consistent for different optionalities, but that's a separable question.
So, the take away from that parallel pitch is that we can teach the compiler to understand that optional values can propagate escapability.
Keeping the ball rolling: We learned that optional can, with some work, propagate closures escapability.
We have at the moment two options (apart from the obvious third one of doing nothing).
add @nonescaping, having default optional closures as escaping (no change on default)
change the default of optional closures to be nonescaping.
none of these options. I'm happy the way closures work with optional right now.
My personal preference would be for the second one, having uniform closure escapability handling, but I understand that it is unclear wether or not changing default for Optional closure would break ABI stability. It's something to be investigated.
Let me know your preference, please. And thank you all.
I didn't write it explicitly, but the option "change the default of optional closures to be nonescaping" assumes that then you can mark as @escaping Optional closures just like you do with simple closures.