Even this small example I think this is still a little fiddly. If we add
another required parameter to the Markdown initializer:
let readme = String(contentsOfFile: “README.md”).flatMap {
Markdown(string: $0, flavor: .github) }
this starts to feel a little inside-out and crufty to me.
> On 12 Dec 2017, at 05:54, Félix Cloutier <[email protected]> wrote:
>
> 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] <mailto:[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] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution