> 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

Reply via email to