<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 14, 2017, at 9:40 PM, Slava Pestov via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">-1.<div class=""><br class=""></div><div class="">We already have a related feature for stored properties in structs and classes, and it causes a performance problem when compiling multi-file modules in non-WMO mode. Suppose you have:<div class=""><br class=""></div><div class="">— a.swift —</div><div class=""><br class=""></div><div class="">struct Box {</div><div class="">&nbsp; var x = &lt;some very complex expression here with lots of overloads and generics&gt;</div><div class="">}</div><div class=""><br class=""></div><div class="">— b.swift —</div><div class=""><br class=""></div><div class="">func takesABox(_: Box) {}</div><div class=""><br class=""></div><div class="">— c.swift —</div><div class=""><br class=""></div><div class="">func returnsABox() -&gt; Box { return Box(x: …) }</div><div class=""><br class=""></div><div class="">When you run ‘swiftc a.swift b.swift c.swift’, we actually invoke the compiler three times:</div><div class=""><br class=""></div><div class="">swiftc -frontend -primary-file a.swift b.swift c.swift</div><div class=""><div class="">swiftc -frontend a.swift -primary-file b.swift c.swift</div></div>swiftc -frontend a.swift b.swift&nbsp;-primary-file&nbsp;c.swift<div class=""><div class=""><br class=""></div><div class="">In the first invocation, we’re emitting the declaration of ‘struct Box’ itself, so we have to type check its members, and infer the type of ‘x’. In the second invocation, we end up type checking takesABox(), which references the ‘Box’ type in its parameter list, so again we have to type check the members of ‘Box’ so that we know the ABI for ‘takesABox()’. And the third time, we’re type checking ‘returnsABox()’, which has ‘Box’ in its return type, so again, it has to be type checked so that we know its layout. This means the complex expression will be type checked a total of three times.</div><div class=""><br class=""></div><div class="">Now if you change a.swift to</div><div class=""><br class=""></div><div class="">struct Box {</div><div class="">&nbsp; var x: Int = &lt;some very complex expression&gt;</div><div class="">}</div><div class=""><br class=""></div><div class="">Then the expression only has to be type checked when compiling a.swift, so that we can emit the initializer for Box, but b.swift and c.swift immediately know the layout of Box without type checking the initializer (because the property type is declared explicitly).</div><div class=""><br class=""></div><div class="">If we allowed default argument types to be omitted, you would introduce the potential for similar compile time slowdowns. It would also create interesting circularity issues:</div><div class=""><br class=""></div><div class="">func foo(a = bar())</div><div class="">func bar(a = foo())</div><div class=""><br class=""></div></div></div></div></div></blockquote><div><br class=""></div><div>To be fair, the compiler is currently able to handle a similar situation:</div><div><br class=""></div><div><div style="margin: 0px 0px 0px 33.7px; text-indent: -33.8px; line-height: normal; font-family: Menlo;" class=""><span style="color: #c900a4" class="">struct</span> Foo {</div><div style="margin: 0px 0px 0px 67.4px; text-indent: -67.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="color: #c800a4" class="">static</span> <span style="color: #c900a4" class="">let</span> foo <span style="color: #c800a4" class="">=</span> Bar<span style="color: #c800a4" class="">.</span>bar</div><div style="margin: 0px 0px 0px 33.7px; text-indent: -33.8px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px 0px 0px 33.7px; text-indent: -33.8px; line-height: normal; font-family: Menlo; min-height: 16px;" class=""><br class=""></div><div style="margin: 0px 0px 0px 33.7px; text-indent: -33.8px; line-height: normal; font-family: Menlo;" class=""><span style="color: #c900a4" class="">struct</span> Bar {</div><div style="margin: 0px 0px 0px 67.4px; text-indent: -67.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="color: #c800a4" class="">static</span> <span style="color: #c900a4" class="">let</span> bar <span style="color: #c800a4" class="">=</span> Foo<span style="color: #c800a4" class="">.</span>foo</div><div style="margin: 0px 0px 0px 33.7px; text-indent: -33.8px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px 0px 0px 33.7px; text-indent: -33.8px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px 0px 0px 33.7px; text-indent: -33.8px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal; color: rgb(242, 0, 4);" class=""><b class="">error: 'foo' used within its own type</b></div><div style="margin: 0px; line-height: normal; color: rgb(242, 0, 4);" class=""><b class="">&nbsp; &nbsp; static let foo = Bar.bar</b></div><div style="margin: 0px; line-height: normal; color: rgb(242, 0, 4);" class=""><b class="">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ^</b></div><div style="margin: 0px; line-height: normal; color: rgb(242, 0, 4);" class=""><b class="">error: could not infer type for 'foo'</b></div><div style="margin: 0px; line-height: normal; color: rgb(242, 0, 4);" class=""><b class="">&nbsp; &nbsp; static let foo = Bar.bar</b></div><div style="margin: 0px; line-height: normal; color: rgb(242, 0, 4);" class=""><b class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;^</b></div></div></div><div><br class=""></div><div>I definitely understand wanting to reduce inference along these boundaries, but type inference for struct members can be extremely useful.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div class="">Here, you’d have recursion between the declaration checker and recursion checker when you go to type check either one of the two functions.</div><div class=""><br class=""></div><div class="">While neither of these challenges are insurmountable — we definitely plan on doing more to speed up the expression type checker, and circularity issues in declaration checking are also something we’ve been chipping away at in recent months — I would be against introducing any language features which make things worse in this regard.</div><div class=""><br class=""></div><div class="">Going back to the my original example here, Jordan Rose once suggested that stored properties inside types should always require a declared type — this might be too drastic for many people’s tastes, but I would definitely be in favor of that from an implementor's perspective ;-)</div><div class=""><br class=""></div><div class="">Slava</div><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Mar 10, 2017, at 1:40 PM, Kilian Koeltzsch via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi all,<div class=""><br class=""></div><div class="">I sent the message below to swift-users@ ~a day ago, but this might be a better place to ask and gather some discussion. It is a rather minor suggestion and I'm just looking for some opinions.</div><div class=""><br class=""></div><div class="">Declaring a function that has default parameters currently looks like this:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(186, 45, 162);">func</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;foo(bar:&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">String</span><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp;=&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">"baz"</span><span class="" style="font-variant-ligatures: no-common-ligatures;">) {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(62, 30, 129);">print</span><span class="" style="font-variant-ligatures: no-common-ligatures;">(bar)</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;">}</span></div></div><div class=""><br class=""></div><div class="">Now I'm wondering if there would be any problems if it were possible to omit the type annotation for default params and let Swift's type inference handle that.&nbsp;</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;foo(bar =&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(209, 47, 27);">"baz"</span><span class="" style="font-variant-ligatures: no-common-ligatures;">) {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;">&nbsp; &nbsp;&nbsp;</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(62, 30, 129);">print</span><span class="" style="font-variant-ligatures: no-common-ligatures;">(bar)</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures;">}</span></div></div><div class=""><br class=""></div><div class="">It feels to be equivalent to omitting type annotations with variable declarations. Obviously more complex types would still require annotations being specified. Off the top of my head I can't think of any negative ramifications this might bring, be it in simple function/method declarations or protocol extensions and elsewhere.&nbsp;</div><div class="">Any further input or examples for situations where this might cause issues would be much appreciated :)</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Kilian</div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>