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

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


I don't think I can (fully) agree with you, because a closure purity is not
something you "define". It's rather what you use inside. Though I totally
understand your concern and a wish to have localized errors.

However, I think it's totally consistent if you use a full form in a way:

{ (a) => B in
return a.toB()
}

What I mean is that short form can auto determine. If you want to be
explicit... use the long form.

Would this work for you, @Matthew?

On Sat, 18 Feb 2017 at 0:09 Matthew Johnson <matthew at anandabits.com> wrote:

> On Feb 17, 2017, at 4:05 PM, Daniel Leping <daniel at crossroadlabs.xyz>
> wrote:
>
> 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.
>
>
> I’m not sure about this.  I would like the ability to syntactically state
> the intent that a closure is pure, and ideally do so in a way that doesn’t
> lose the conciseness of the closure (i.e. we shouldn’t have to give up any
> of the syntactic sugar available for simple closures).  A big benefit of
> allowing us to state intent like this is that it localizes error messages.
>
>
> 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/414dc7da/attachment.html>


More information about the swift-evolution mailing list