-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())
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
> <[email protected]> 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
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution