You talk about flatMap without giving an example. The readme isn't that bad 
with it, IMO:

if let readme = String(contentsOfFile: "README.md").flatMap(Markdown) {
        // use contents here
}

That doesn't work when you need multiple optional parameters. In my own 
experience, that hasn't been a huge problem, though.

Félix

> Le 11 déc. 2017 à 08:30, Jared Khan via swift-evolution 
> <[email protected]> a écrit :
> 
> Hi all,
> 
> I'd like to propose a syntax addition that acts to ease some things that I 
> believe should fall under the umbrella of 'optional chaining'. Optional 
> chaining allows us to access the properties of an optional value and return 
> nil if any link in that chain breaks. I propose we introduce syntax to allow 
> similar chaining when passing optional valued parameters to functions that 
> expect that parameter to be non-optional.
> 
> The example below is taken from a project I'm working on at the moment:
> 
> 
> // Current
> let readme: Markdown?
> if let rawMarkdown = String(contentsOfFile: "README.md") {
>       readme = Markdown(string: rawMarkdown)
> } else {
>       readme = nil
> }
> In this example we want to perform an operation, the initialisation of a 
> 'Markdown' type, with our raw text if it exists and get nil otherwise. This 
> is rather verbose
> 
> I propose the following syntax for an alternative:
> 
> 
> // Proposed alternative
> let readme = Markdown(string: String(contentsOfFile: "README.md")?)
> 
> The ? is familiar in its use for optional chaining.
> 
> This would act like syntactic sugar for the flatMap method on Optional. For 
> example:
> 
> (where `john` is of a `Person` type with a property `address: Address?`)
> // func getZipCode(fromAddress address: Address) -> ZipCode
> getZipCode(fromAddress: john.address?)
> 
> // Would be equivalent to…
> john.address.flatMap {
>       getZipCode($0)
> }
> An example with multiple parameters:
> 
> // func getPostageEstimate(source: Address, destination: Address, weight: 
> Double) -> Int
> getPostageEstimate(source: john.address?, destination: alice.address?, 
> weight: 2.0)
> 
> // Equivalent to
> john.address.flatMap { freshVar1 in
>       alice.address.flatMap { freshVar2 in
>               getPostageEstimate(source: freshVar1, destination: freshVar2, 
> weight: 2.0)
>       }
> }
> 
> // Or equally:
> {
>       guard let freshVar1 = john.address,
>               let freshVar2 = alice.address else {
>                       return nil
>       }
> 
>       return getPostageEstimate(source: freshVar1, destination: freshVar2, 
> weight: 2.0)
> }()
> This would only be allowed when the parameter doesn’t already accept 
> Optionals and when the chained value is in fact an optional. We’d want to 
> consider emitting at least the following errors/warnings in the given 
> scenarios:
> 
> 
> let result = myFunc(3?)
> // error: cannot use optional chaining on non-optional value of type 'Int'
> 
> // func myFunc2(x: String?) -> String
> let result = myFunc2(x: john.address?)
> // error: cannot use optional argument chaining on argument of optional type
> let result = myFunc(nil?)
> // warning: optional argument chaining with nil literal always results in nil
> 
> Seeking your thoughts on this idea, the specific syntax, and more use case 
> examples.
> 
> Best,
> 
> Jared
> 
> _______________________________________________
> 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

Reply via email to