> On Dec 21, 2015, at 12:20 PM, T.J. Usiyan <[email protected]> wrote: > > 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.
Yes, this is worth considering, but it would be nice to avoid this if possible. There are two interesting related-but-different problems that could be tackled here: 1. Optimization hints: These would align to llvm’s readnone/readonly attributes (const/pure in GCC nomenclature). 2. Expanding the existing ‘let’ language model from properties to functions: this would allow computed lets. I’m personally more interested in making #2 happen. It is the attribute that (like noescape) would need to permeate the type system. #1 could be interesting, but it could also be a different thing that is an attribute of a declaration, not an attribute of the declaration’s type. LLVM also supports a number of other interesting attributes that can be useful to expose someday in Swift, but I’m not keen to do that unless there is a very strong and specific need to do so: http://llvm.org/docs/LangRef.html#id671 -Chris > > On Mon, Dec 21, 2015 at 2:55 PM, Chris Lattner via swift-evolution > <[email protected] <mailto:[email protected]>> wrote: > On Dec 19, 2015, at 9:00 PM, Jimmy Sambuo via swift-evolution > <[email protected] <mailto:[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: >> >> The function must have a return value >> This function can only call other pure functions >> 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 >> <https://dlang.org/spec/function.html#pure-functions>) or the noSideEffect >> pragma in Nim >> (http://nim-lang.org/docs/manual.html#pragmas-nosideeffect-pragma >> <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 <http://www.sambuo.com/> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] <mailto:[email protected]> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> > > > > _______________________________________________ > swift-evolution mailing list > [email protected] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
