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 < [email protected]> wrote: > On Dec 19, 2015, at 9:00 PM, Jimmy Sambuo via swift-evolution < > [email protected]> 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 > [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
