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