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 <felixclout...@icloud.com> 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 >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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 >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution