[swift-evolution] Infer types of default function parameters
Jaden Geller
jaden.geller at gmail.com
Wed Mar 15 00:17:27 CDT 2017
> On Mar 14, 2017, at 9:40 PM, Slava Pestov via swift-evolution <swift-evolution at swift.org> wrote:
>
> -1.
>
> 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:
>
> — a.swift —
>
> struct Box {
> var x = <some very complex expression here with lots of overloads and generics>
> }
>
> — b.swift —
>
> func takesABox(_: Box) {}
>
> — c.swift —
>
> func returnsABox() -> Box { return Box(x: …) }
>
> When you run ‘swiftc a.swift b.swift c.swift’, we actually invoke the compiler three times:
>
> swiftc -frontend -primary-file a.swift b.swift c.swift
> swiftc -frontend a.swift -primary-file b.swift c.swift
> swiftc -frontend a.swift b.swift -primary-file c.swift
>
> 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.
>
> Now if you change a.swift to
>
> struct Box {
> var x: Int = <some very complex expression>
> }
>
> 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).
>
> 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:
>
> func foo(a = bar())
> func bar(a = foo())
>
To be fair, the compiler is currently able to handle a similar situation:
struct Foo {
static let foo = Bar.bar
}
struct Bar {
static let bar = Foo.foo
}
error: 'foo' used within its own type
static let foo = Bar.bar
^
error: could not infer type for 'foo'
static let foo = Bar.bar
^
I definitely understand wanting to reduce inference along these boundaries, but type inference for struct members can be extremely useful.
> Here, you’d have recursion between the declaration checker and recursion checker when you go to type check either one of the two functions.
>
> 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.
>
> 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 ;-)
>
> Slava
>
>
>> On Mar 10, 2017, at 1:40 PM, Kilian Koeltzsch via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>
>> Hi all,
>>
>> 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.
>>
>> Declaring a function that has default parameters currently looks like this:
>>
>> func foo(bar: String = "baz") {
>> print(bar)
>> }
>>
>> 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.
>>
>> func foo(bar = "baz") {
>> print(bar)
>> }
>>
>> 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.
>> Any further input or examples for situations where this might cause issues would be much appreciated :)
>>
>> Cheers,
>> Kilian
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170314/e0b5cb36/attachment.html>
More information about the swift-evolution
mailing list