[swift-evolution] [Proposal idea] Support for pure functions
T.J. Usiyan
griotspeak at gmail.com
Mon Dec 21 14:20:14 CST 2015
I have been thinking about this proposal since the list opened up. I think
that @read(none|only) should be considered as an alternative. Just as in
clang and the optimizer annotations @read(none) would be the attribute
described and @read(only) could read global variables but could not write.
Is it possible to generate a runtime error if we guarantee that function A
is pure, only to call it and 'find out' that it isn't? If we can, then do
try syntax could be considered.
On Mon, Dec 21, 2015 at 2:55 PM, Chris Lattner via swift-evolution <
swift-evolution at swift.org> wrote:
> On Dec 19, 2015, at 9:00 PM, Jimmy Sambuo via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
> My proposal is to add a `pure` keyword/attribute to Swift.
>
> I’m a fan of this in concept, and the mechanics for this feature would
> probably allow us to have safe “computed lets” as well. My one concern
> about this is that there probably has to be some way to unsafely “force a
> call to a non-pure function to be allowed in a pure one”, both because of
> type system limitations as well as interoperability with C and other
> languages. Even ignoring issues around errno, it would be sad for a pure
> function to not be able to call “sin(x)” just because it weren’t marked
> __attribute__((const)).
>
> A proposal in this area should consider how “pure” would interact with the
> type system, and it would probably make sense as an attribute @pure instead
> of a declmodifier.
>
> -Chris
>
>
> Similar to throws, you would mark a function as pure to say it will not
> cause any observable side-effects and hold referential transparency:
>
> ```swift
>
> func pure add(x: Int, y: Int) -> Int {
>
> return x + y
>
> }
>
> ```
>
> By adding this attribute, the function is guaranteed to have some
> properties:
>
> 1. The function must have a return value
> 2. This function can only call other pure functions
> 3. This function cannot access/modify global or static variables.
>
> ```swift
>
> func pure getDate() -> NSDate {
>
> return NSDate.date() // Error: pure function 'getDate' cannot call
> impure function 'date'
>
> }
>
> ```
>
> This would be similar to the pure keyword in D (
> https://dlang.org/spec/function.html#pure-functions) or the noSideEffect
> pragma in Nim (
> http://nim-lang.org/docs/manual.html#pragmas-nosideeffect-pragma).
>
> My motivation for this is that I want to create applications that follow a
> "Functional Core, Imperative Shell" style [Gary Bernhardt]. By marking all
> of my functions within the functional core as pure, the compiler can help
> me if I accidentally start writing impure functions. In theory, this should
> make my application simpler and more testable. Reviewing pull requests will
> also be simpler since in the functional portion of my codebase, checking
> for pure can be a criteria. Ideally, I'd run a static analyzer to see that
> I have more pure functions than impure ones, which should help me control
> complexity by encouraging me to have a larger "value" layer and smaller
> "object" layer [Andy Matuschak].
>
> Logically, I think of this as Swift having all functions return
> "Implicitly Impure Values" (similar to how every object from objective-c is
> an implicitly unwrapped optional). All existing Swift functions are
> actually returning a IO<SomeType>, and functions using that are implicitly
> unwrapping them. Swift can be super nice by hiding this fact, making the
> language much more familiar and accessible to developers not used to
> purity. Adding `pure` allows devs to tap into the compiler's power and
> prevent unwanted side-effects without directly exposing the IO type.
>
> The benefits I see are:
>
> - Explicit intentions - This allows design decisions to be
> communicated clearly to other developers and maintainers, as well as the
> compiler and other static analysis tools.
> - Compile-time guarantee - The compiler can help prevent unintentional
> state modifications.
> - Encouragement of better state management practices - More people
> will be aware of the concept of functional purity and may try to design
> their code to have more pure functions, which should make more code simpler
> and testable. This isn't a guarantee it will happen, but more people should
> understand it if it brings concrete results instead of just being an
> abstract concept.
> - Reduced cognitive load when understanding code - More pure functions
> should make it easier to reason about code.
> - Opt-in to purity - Swift will be just as accessible to new
> developers, but experienced developers will be able to take advantage of
> this.
> - Backwards compatible (mostly) - Existing codebases should still
> compile without any change (unless pure was used as a variable/method/class
> name).
>
> Of course, there are risks of this feature. Some of the risks include:
>
> - This could make the language more difficult to work with. Developers
> maintaining an existing codebase with lots of pure function may become
> confused or frustrated when they realize they cannot do easy things such as
> logging within the method.
> - A counterargument to this may be that when Swift was introduced,
> optionals also made the language difficult to use. People implicitly
> unwrapped them just so things will compile, or returned them from methods
> without much consideration to what that implies. Nevertheless, this made
> Swift a safer language to use by explicitly when nil is a possible value.
> Developers are more conscious about nil being a potential value. Similarly,
> I think developers should be more aware about side-effect causing
> functions. Being clear about this and separating these concerns should
> bring about more safer and testable Swift applications.
> - Implementation of this feature could be difficult. Swift can
> implement it in several different ways depending on the desired result of
> this feature, such as having stronger or weaker purity guarantees to make
> the feature easier to use or simpler to implement. An effect system may
> have to be created.
> - Alternatively, this could be done in a lightweight manner where
> the feature is introduced and known "pure-like" functions are marked
> in swift-corelibs-foundation.
>
> To be honest, I don't have much experience in languages that have this
> feature. I would imagine many people are interested in the notion of pure
> functions, but the question here is if it would be worth it, feasible, or
> even aligned with Swift's goals to have this feature. I'm half-expecting
> that this has already been brought up and determined to be out of scope or
> not a good idea.
>
> Thanks for your consideration. Please let me know what you think.
> --
> Jimmy Sambuo
> www.sambuo.com
> _______________________________________________
> 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/20151221/c6e463f3/attachment.html>
More information about the swift-evolution
mailing list