<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div></div><div><br></div><div><br>Am 03.09.2016 um 18:45 schrieb Justin Jia <<a href="mailto:justin.jia.developer@gmail.com">justin.jia.developer@gmail.com</a>>:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 4, 2016, at 12:19 AM, Thorsten Seitz <<a href="mailto:tseitz42@icloud.com" class="">tseitz42@icloud.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><br class="Apple-interchange-newline"><br class="">Am 15.08.2016 um 19:05 schrieb Justin Jia via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>>:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div class="">I agree that being explicit is nice and I also like to use `guard`.</div><div class=""><br class=""></div><div class="">But according to my observation, usually it is easier to make mistakes if we choose to use `guard`.</div><div class=""><br class=""></div><div class="">Let me give you a fake real world example.</div><div class=""><br class=""></div><div class="">With `guard`, you need to be really careful when you want to add new expression (people usually will add to the end of the function).</div><div class=""><br class=""></div><div class="">```</div><div class="">func updateCell(cell: Cell, data: CellData) {</div><div class=""> cell.label.text = data.title</div><div class=""> guard let imageName = data.imageName else { return }</div><div class=""> cell.sublabel.text = cell.humanize(imageName)</div><div class=""> guard let image = UIImage(named: imageName) else { return }</div><div class=""> cell.addBackgroundImage(image)</div><div class=""> // Let's say we changed the design and added a new heading that depends on image name</div><div class=""> cell.heading = String(imageName.characters.first) // This won't be called if image is nil!</div><div class="">}</div><div class="">```</div><div class=""><br class=""></div><div class="">With `if let`, it is really hard to read. This will become more complicated if we add more attributes to cell.</div><div class=""><br class=""></div><div class="">```</div><div class="">func updateCell(cell: Cell, data: CellData) {</div><div class=""> cell.label.text = data.title</div><div class=""> if let imageName = data.imageName {</div><div class=""> cell.sublabel.text = cell.humanize(imageName)</div><div class=""> if let image = UIImage(name: imageName) {</div><div class=""> cell.addBackgroundImage(image)</div><div class=""> }</div><div class=""> cell.heading = String(imageName.characters.first)</div><div class=""> }</div><div class="">}</div><div class="">```</div><div class=""><br class=""></div><div class="">With the proposed syntax:</div><div class=""><br class=""></div><div class="">```</div><div class="">func updateCell(cell: Cell, data: CellData) {</div><div class=""> cell.label.text = data.title</div><div class=""> let imageName = data.imageName // imageName is optional</div><div class=""> cell.sublabel.text = cell.humanize(imageName?)</div><div class=""> let image = UIImage(named: imageName?) // image is optional</div><div class=""> cell.addBackgroundImage(image?)</div><div class=""> cell.heading = String(imageName.characters.first?)</div><div class="">}</div><div class="">```</div><div class=""><br class=""></div><div class=""><div class="">This is really easy to read. And everything works correctly.</div></div></div></blockquote><div class=""><br class=""></div>It is even easier if you define the methods on Cell to take optional arguments. </div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Then you can write the code like in your last example and don't even need the proposed syntax:<div class=""><br class=""></div><div class="">class Cell {</div><div class=""> let label = UILabel()</div><div class=""> let sublabel = UILabel()</div><div class=""> var heading: String?</div><div class=""> func humanize(_ string: String?) -> String {...} // optional argument</div><div class=""> func addBackgroundImage(_ image: UIImage?) // optional argument</div><div class="">}</div><div class=""><br class=""></div><div class="">extension UIImage {</div><div class=""> init?(named imageName: String?) {...}</div><div class="">}</div><div class=""><br class=""></div><div class=""><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">extension String {</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""> init?(named imageName: Character?) {...}</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">}</span></div></div><div class=""><br class=""></div><div class=""><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">func updateCell(cell: Cell, data: CellData) {</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""> cell.label.text = data.title</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""> let imageName = data.imageName</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""> cell.sublabel.text = cell.humanize(imageName)</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""> let image = UIImage(named: imageName)</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""> cell.addBackgroundImage(image)</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""> cell.heading = String(imageName?.characters?.first)</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">}</span></font></div></div><div class=""><br class=""></div><div class="">-Thorsten </div></div></div></blockquote></div><br class=""><div class=""><br class=""></div><div class="">Quoting another email:</div><div class=""><br class=""></div><div class=""><div class=""></div><blockquote type="cite" class=""><div class="">Actually there is an easy fix: make all functions accept optionals. I think this is a really bad idea because sometimes functions are designed to accept non-optionals.</div><div class=""><br class=""></div><div class="">e.g.</div><div class=""><br class=""></div><div class="">```</div><div class="">func addSubview(_ view: UIView) { }</div><div class="">```</div><div class=""><br class=""></div><div class="">It doesn’t make sense if we want to add nil as the subview, so we choose to write code like this:</div><div class=""><br class=""></div><div class="">```</div><div class="">if let view = view {</div><div class=""> addSubview(view)</div><div class="">}</div><div class="">```</div></blockquote><div class=""><br class=""></div></div><div class=""><div class=""></div></div></div></blockquote><br><div>I agree. The proposal effectively does just that, though: turn every function into a function accepting optionals (returning nil if any argument is nil). I would prefer to do this explicitly in cases where it makes sense and use map or let-bindings elsewhere.</div><div><br></div><div>-Thorsten </div></body></html>