[swift-evolution] [Pitch] Support for pure functions. Part n + 1.

Daniel Leping daniel at crossroadlabs.xyz
Fri Feb 17 16:05:40 CST 2017


I personally like a lot => syntax for several reasons:
1. Consistent
2. Enforced return type

As for the closures, I don't think we need an indication here. If it calls
any impure function or captures a variable from outside - it's impure by
definition. The compiler should decide if a closure can be treated pure.
Same as with throwing.

As for the situation with currying (and other compositions), the situation
is a lot more complicated than with rethrows. However, it's still
deductible in compile time with the same mechanism as described above for
closures.

I tend to agree we could use ~> (looks good to me... volatile :)) for the
function type definitions as an "unknown purity". The return type purity
dependence graph can be built automatically at compile time. With this
graph compiler can determine the returned function purity in every place
function is used.

The use of ~> should of course be limited to argument and return types of
pure functions only. I think there might be a possibility of use in
typealias, but need to think more about it.

On Fri, 17 Feb 2017 at 22:59 Matthew Johnson via swift-evolution <
swift-evolution at swift.org> wrote:

> On Feb 17, 2017, at 2:52 PM, Jonathan Hull via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Out of curiosity, what are the benefits to being able to define that a
> closure must be pure as a parameter/type definition, as opposed to defining
> a particular closure to being pure while being passed?  What guarantees
> does it give you as the caller of the closure?
>
>
> If you only accept pure closures and otherwise meet the criteria of a pure
> function then you are pure.  If you have a function like that and want to
> accept both pure and impure closures and receive the purity of the closure
> provided then we need syntax indicating something similar to `rethrows`,
> but for purity.
>
>
> Thanks,
> Jon
>
>
> On Feb 16, 2017, at 1:18 PM, T.J. Usiyan <griotspeak at gmail.com> 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 <jhull at gbis.com> 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 <
> swift-evolution at swift.org> 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
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170217/ec93b50d/attachment.html>


More information about the swift-evolution mailing list