Now that I've thought more about it, I have a question. Escaping/unescaping is an important concept to have in the language: if the API provider makes the promise that a closure is non-escaping, the API client doesn't have to worry about the closure capturing variables and creating strong references to them.
But in the case of pure functions, I fail to get the benefit from the examples. Could someone explain to me the advantages with a more in-depth example? > On 16 Feb 2017, at 22:39, Dennis Weissmann via swift-evolution > <[email protected]> wrote: > > I think discovering them is not the problem, the question is if you really > want them to be annotated pro-actively by the compiler - I don't think so. > > Your comparison with @escape is both right and wrong :) It's wrong in the > sense that @escaping is a relaxing attribute while @pure is a constraining > one. > > You can pass a non-escaping closure where an escaping one is required, but no > the other way around. > This would be equivalent to an (relaxing) @impure attribute, you could still > pass a pure function wherever an impure one is required but no the other way > around. > > With @pure it's the other way around, you cannot pass an impure function > where a pure one is required. > > Imagine the compiler annotating every pure function automatically with @pure, > you could not override it with an impure function even though you maybe never > though of making it pure, it just happened by accident. > > - Dennis > >> On Feb 16, 2017, at 10:25 PM, Sean Heber via swift-evolution >> <[email protected]> wrote: >> >> Couldn’t pure functions be discovered by the compiler like how the compiler >> already discovers an escaping vs. non-escaping function? Then perhaps pure >> only needs to be an attribute on closure parameter - just like how @escaping >> works? >> >> l8r >> Sean >> >> >>> On Feb 16, 2017, at 3:18 PM, T.J. Usiyan via swift-evolution >>> <[email protected]> wrote: >>> >>> I am ok with a keyword but `pure` in front of func doesn't work well with >>> inline closures. >>> >>> A few people talked through many of these issues starting with this tweet. >>> https://twitter.com/griotspeak/status/832247545325842432 >>> >>> On Thu, Feb 16, 2017 at 4:13 PM, Jonathan Hull <[email protected]> wrote: >>> +1 for the idea of pure functions in swift. Seems like it would enable a >>> lot of good optimizations (in some cases even just evaluating the function >>> at compile time). >>> >>> -1 on the specific notation. I would much rather just put the word ‘pure’ >>> in front of ‘func’, the same way we put ‘mutating' in front of mutating >>> functions… it seems to me like these are part of the same family. >>> >>> I agree we should allow inout. >>> >>> Thanks, >>> Jon >>> >>>> On Feb 16, 2017, at 9:03 AM, T.J. Usiyan via swift-evolution >>>> <[email protected]> wrote: >>>> >>>> # Pure Functions >>>> >>>> * Proposal: >>>> [SE-NNNN](https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md) >>>> * Author(s): [TJ Usiyan](https://github.com/griotspeak) >>>> * Status: **Awaiting review** >>>> * Review manager: TBD >>>> >>>> ## Introduction >>>> >>>> Some functions are, essentially, only meant to be transformations of their >>>> input and–as such–do not and should not reference any variables other than >>>> those passed in. These same functions are not meant to have any effects >>>> other than the aforementioned transformation of input. Currently, Swift >>>> cannot assist the developer and confirm that any given function is one of >>>> these 'pure' functions. To facilitate this, this proposal adds syntax to >>>> signal that a function is 'pure'. >>>> >>>> 'pure', in this context, means: >>>> 1. The function must have a return value >>>> 1. This function can only call other pure functions >>>> 1. This function cannot access/modify global or static variables. >>>> >>>> ## Motivation >>>> >>>> Consider the following example where `_computeNullability(of:)` is meant >>>> to create its output solely based on the provided recognizer. >>>> >>>> ``` >>>> class Recognizer { >>>> var nullabilityMemo: Bool? >>>> var isNullable: Bool { >>>> func _computeNullability(of recognizer: Recognizer) -> Bool {…} >>>> if let back = nullabilityMemo { >>>> return back >>>> } else { >>>> let back = _computeNullability(of: self) >>>> nullabilityMemo = back >>>> return back >>>> } >>>> } >>>> } >>>> ``` >>>> if `_computeNullability(of:)` is recursive at all, there exists a real >>>> potential to accidentally reference `self` in its body and the mistake, >>>> depending on circumstance, can be terribly subtle. Converting >>>> `_computeNullability(of:)` to a `static` function is an option but >>>> obfuscates the fact that it is *only* to be called within `isNullable`. >>>> >>>> >>>> ## Proposed solution >>>> >>>> Given the ability to indicate that `_computeNullability(of:)` is a 'pure' >>>> function, the developer gains assurance from the tooling that it doesn't >>>> reference anything or cause any side effects. >>>> >>>> >>>> ``` >>>> class Recognizer { >>>> var nullabilityMemo: Bool? >>>> var isNullable: Bool { >>>> pfunc _computeNullability(of recognizer: Recognizer) -> Bool {…} >>>> if let back = nullabilityMemo { >>>> return back >>>> } else { >>>> let back = _computeNullability(of: self) >>>> nullabilityMemo = back >>>> return back >>>> } >>>> } >>>> } >>>> ``` >>>> >>>> ## Detailed design >>>> >>>> This proposal introduces a new annotation `=>`, which is to be accepted >>>> everywhere `->` currently is. Members created using this kewyord must >>>> follow the rules listed in the introduction. >>>> >>>> ## Impact on existing code >>>> >>>> This is an additive feature unless alternative 2 is chosen and, as such, >>>> should not require an effect on existing code. It could be used to >>>> annotate closures accepted by methods in the standard library such as >>>> `map`, `filter`, and `reduce`. While this would fit well with their >>>> typical use, such a change is not necessarily part of this proposal. >>>> >>>> ## Alternatives considered >>>> >>>> It should be noted that neither of these alternatives can remain >>>> consistent for inline closures. >>>> 1. keyword `pfunc` (pronounciation: pifəŋk) for 'pure' functions. >>>> 2. `proc` keyword for 'impure' functions and 'func' for 'pure' functions. >>>> This would be a massively source breaking change and, as such, is unlikely >>>> to have any feasibility. It is, however, the most clean semantically, in >>>> my opinion. >>>> >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> [email protected] >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] >>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution > _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
