Infer types of default function parameters


(Kilian Koeltzsch) #1

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 :slight_smile:

Cheers,
Kilian


(David Sweeris) #2

Tentatively +1… I still haven’t thought through it as much as I’d like to.

- Dave Sweeris

···

On Mar 10, 2017, at 1:40 PM, Kilian Koeltzsch via swift-evolution <swift-evolution@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 :slight_smile:


(TJ Usiyan) #3

-1 from me. I prefer explicitness at function boundaries.

···

On Fri, Mar 10, 2017 at 4:55 PM, David Sweeris via swift-evolution < swift-evolution@swift.org> wrote:

On Mar 10, 2017, at 1:40 PM, Kilian Koeltzsch via swift-evolution < > swift-evolution@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 :slight_smile:

Tentatively +1… I still haven’t thought through it as much as I’d like to.

- Dave Sweeris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Rien) #4

0

Its not something I would use, but I don’t see why not.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl

···

On 10 Mar 2017, at 22:40, Kilian Koeltzsch via swift-evolution <swift-evolution@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 :slight_smile:

Cheers,
Kilian
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Haravikk) #5

I like the idea but I'm afraid I don't think I can support it.

I think it is more important for function/method declarations to have as explicit a signature as possible; I mean, I'm not even that comfortable with the ability to omit -> Void on non-returning functions (I always include it just to be consistent).

As others point out, while this makes sense for types where there's only one obvious choice to infer, it's not quite so clear on things like ints where a function really needs to be absolutely clear on what type/width of int it expects, since it's not something you want to have to change in future.

One alternative I thought of was an operator for this purpose, e.g- := (chosen since the colon kind of suits the omitted type declaration); this would allow a developer to be explicit about wanting Swift to infer the type, but it would be inconsistent with regular variables where it's always inferred, so I'm not sure if it'd be a good option anyway.

Sorry, I do agree that it feels inconsistent that a function default doesn't behave more like a variable's initialisation, but at the same time they are two slightly different concepts so that's not necessarily a bad thing.

···

On 10 Mar 2017, at 21:40, Kilian Koeltzsch via swift-evolution <swift-evolution@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 :slight_smile:


(Jean-Daniel) #6

-1

It would be inconsistent to allow it for deterministic literals (String) and not for non deterministic literal (int which can be either a Int, Uint, Float, …)

···

Le 10 mars 2017 à 22:40, Kilian Koeltzsch via swift-evolution <swift-evolution@swift.org> a écrit :

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 :slight_smile:

Cheers,
Kilian
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Ben Rimmington) #7

Previously:

<https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160509/016982.html>

<http://discourse.natecook.com/t/proposal-allow-function-argument-type-to-be-omitted-when-passing-a-default-value-from-which-it-can-be-inferred/1540>

···

On 10 Mar 2017, at 21:40, Kilian Koeltzsch 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 :slight_smile:

Cheers,
Kilian


(Slava Pestov) #8

-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 :wink:

Slava

···

On Mar 10, 2017, at 1:40 PM, Kilian Koeltzsch via swift-evolution <swift-evolution@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 :slight_smile:

Cheers,
Kilian
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Daniel Leping) #9

I'm always positive with shorthand declarations, though this is a good
example of ambiguity pron case.

Signatures are signatures. Let's not mess with them.

···

On Sat, 11 Mar 2017 at 11:19 Haravikk via swift-evolution < swift-evolution@swift.org> wrote:

On 10 Mar 2017, at 21:40, Kilian Koeltzsch via swift-evolution < > swift-evolution@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 :slight_smile:

I like the idea but I'm afraid I don't think I can support it.

I think it is more important for function/method declarations to have as
explicit a signature as possible; I mean, I'm not even that comfortable
with the ability to omit -> Void on non-returning functions (I always
include it just to be consistent).

As others point out, while this makes sense for types where there's only
one obvious choice to infer, it's not quite so clear on things like ints
where a function really needs to be absolutely clear on what type/width of
int it expects, since it's not something you want to have to change in
future.

One alternative I thought of was an operator for this purpose, e.g- :=
(chosen since the colon kind of suits the omitted type declaration); this
would allow a developer to be explicit about wanting Swift to infer the
type, but it would be inconsistent with regular variables where it's always
inferred, so I'm not sure if it'd be a good option anyway.

Sorry, I do agree that it feels inconsistent that a function default
doesn't behave more like a variable's initialisation, but at the same time
they *are* two slightly different concepts so that's not necessarily a
bad thing.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Sweeris) #10

If I’m not mistaken, even with `bar = “baz”`, `String` is merely the default inferred type. It could be anything that conforms to `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a way to make a function implicitly generic:
func foo(bar = "baz") {…}
becomes:
func foo<T: ExpressibleByStringLiteral>(bar: T = "baz") {…}

Is there anything we can do with a variable, if all we know of it is that it conforms to `ExpressibleByStringLiteral`? I can’t think of anything… If we had a way to get back the literal string which the variable was initialized with, we could initialize other values with that, but the protocol doesn’t require us to store it. Come to think of it, is there even a way to store a literal value in its “untyped” form? You can declare a variable to of type `IntegerLiteralType`, but the type system then treats it as an `Int`.

So while it looks nice (to me, anyway) I’m not sure you could actually do anything with it. Or am I looking at this wrong?

- Dave Sweeris

···

On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution <swift-evolution@swift.org> wrote:

-1

It would be inconsistent to allow it for deterministic literals (String) and not for non deterministic literal (int which can be either a Int, Uint, Float, …)


(Jaden Geller) #11

-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.

···

On Mar 14, 2017, at 9:40 PM, Slava Pestov via swift-evolution <swift-evolution@swift.org> wrote:

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 :wink:

Slava

On Mar 10, 2017, at 1:40 PM, Kilian Koeltzsch via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@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 :slight_smile:

Cheers,
Kilian
_______________________________________________
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


(Jaden Geller) #12

-1

It would be inconsistent to allow it for deterministic literals (String) and not for non deterministic literal (int which can be either a Int, Uint, Float, …)

If I’m not mistaken, even with `bar = “baz”`, `String` is merely the default inferred type. It could be anything that conforms to `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a way to make a function implicitly generic:
func foo(bar = "baz") {…}
becomes:
func foo<T: ExpressibleByStringLiteral>(bar: T = "baz") {…}

As I understood it, omitting the type would work identically to `let` declarations. A string literal without a type defaults to `String`. Treating it as a generic function is a bad idea IMO.

I don't think this sugar is worth any amount of added complexity. Most function arguments will have not have default values and this have to continue to declare the type, so this would only be more concise in very few cases. I'd prefer the consistency of always having to explicitly declare the argument type at a function boundary.

To call a function, you need to know what type to pass in. This becomes more difficult when not make explicit, particularly when a more complicated expression is used as a default. -1

···

On Mar 11, 2017, at 12:20 PM, David Sweeris via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Is there anything we can do with a variable, if all we know of it is that it conforms to `ExpressibleByStringLiteral`? I can’t think of anything… If we had a way to get back the literal string which the variable was initialized with, we could initialize other values with that, but the protocol doesn’t require us to store it. Come to think of it, is there even a way to store a literal value in its “untyped” form? You can declare a variable to of type `IntegerLiteralType`, but the type system then treats it as an `Int`.

So while it looks nice (to me, anyway) I’m not sure you could actually do anything with it. Or am I looking at this wrong?

- Dave Sweeris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Derrick Ho) #13

+1

I like that python style shorthand.

···

On Sat, Mar 11, 2017 at 6:36 AM Daniel Leping via swift-evolution < swift-evolution@swift.org> wrote:

I'm always positive with shorthand declarations, though this is a good
example of ambiguity pron case.

Signatures are signatures. Let's not mess with them.

On Sat, 11 Mar 2017 at 11:19 Haravikk via swift-evolution < > swift-evolution@swift.org> wrote:

On 10 Mar 2017, at 21:40, Kilian Koeltzsch via swift-evolution < > swift-evolution@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 :slight_smile:

I like the idea but I'm afraid I don't think I can support it.

I think it is more important for function/method declarations to have as
explicit a signature as possible; I mean, I'm not even that comfortable
with the ability to omit -> Void on non-returning functions (I always
include it just to be consistent).

As others point out, while this makes sense for types where there's only
one obvious choice to infer, it's not quite so clear on things like ints
where a function really needs to be absolutely clear on what type/width of
int it expects, since it's not something you want to have to change in
future.

One alternative I thought of was an operator for this purpose, e.g- :=
(chosen since the colon kind of suits the omitted type declaration); this
would allow a developer to be explicit about wanting Swift to infer the
type, but it would be inconsistent with regular variables where it's always
inferred, so I'm not sure if it'd be a good option anyway.

Sorry, I do agree that it feels inconsistent that a function default
doesn't behave more like a variable's initialisation, but at the same time
they *are* two slightly different concepts so that's not necessarily a
bad thing.
_______________________________________________
swift-evolution mailing list
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


(Ben Cohen) #14

-1

It would be inconsistent to allow it for deterministic literals (String) and not for non deterministic literal (int which can be either a Int, Uint, Float, …)

If I’m not mistaken, even with `bar = “baz”`, `String` is merely the default inferred type. It could be anything that conforms to `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a way to make a function implicitly generic:
func foo(bar = "baz") {…}
becomes:
func foo<T: ExpressibleByStringLiteral>(bar: T = "baz") {…}

As I understood it, omitting the type would work identically to `let` declarations. A string literal without a type defaults to `String`. Treating it as a generic function is a bad idea IMO.

More specifically, a string literal without a type defaults to the StringLiteralType typealias:

typealias StringLiteralType = StaticString
let s = "abc"
print(type(of: s))
// prints StaticString

···

On Mar 11, 2017, at 1:17 PM, Jaden Geller via swift-evolution <swift-evolution@swift.org> wrote:
On Mar 11, 2017, at 12:20 PM, David Sweeris via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I don't think this sugar is worth any amount of added complexity. Most function arguments will have not have default values and this have to continue to declare the type, so this would only be more concise in very few cases. I'd prefer the consistency of always having to explicitly declare the argument type at a function boundary.

To call a function, you need to know what type to pass in. This becomes more difficult when not make explicit, particularly when a more complicated expression is used as a default. -1

Is there anything we can do with a variable, if all we know of it is that it conforms to `ExpressibleByStringLiteral`? I can’t think of anything… If we had a way to get back the literal string which the variable was initialized with, we could initialize other values with that, but the protocol doesn’t require us to store it. Come to think of it, is there even a way to store a literal value in its “untyped” form? You can declare a variable to of type `IntegerLiteralType`, but the type system then treats it as an `Int`.

So while it looks nice (to me, anyway) I’m not sure you could actually do anything with it. Or am I looking at this wrong?

- Dave Sweeris
_______________________________________________
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


(Charles Srstka) #15

When you declare a property with an inferred type, it shows with the explicit type in the generated interface. So:

public struct S {
  public let foo = 3
}

becomes:

public struct S {
  public let foo: Int
}

I would presume that the same rule would apply to default parameters in function declarations (although to be fair, I’m also uncertain that we actually need this).

Charles

···

On Mar 11, 2017, at 3:17 PM, Jaden Geller via swift-evolution <swift-evolution@swift.org> wrote:

As I understood it, omitting the type would work identically to `let` declarations. A string literal without a type defaults to `String`. Treating it as a generic function is a bad idea IMO.

I don't think this sugar is worth any amount of added complexity. Most function arguments will have not have default values and this have to continue to declare the type, so this would only be more concise in very few cases. I'd prefer the consistency of always having to explicitly declare the argument type at a function boundary.

To call a function, you need to know what type to pass in. This becomes more difficult when not make explicit, particularly when a more complicated expression is used as a default. -1


(Jaden Geller) #16

-1

It would be inconsistent to allow it for deterministic literals (String) and not for non deterministic literal (int which can be either a Int, Uint, Float, …)

If I’m not mistaken, even with `bar = “baz”`, `String` is merely the default inferred type. It could be anything that conforms to `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a way to make a function implicitly generic:
func foo(bar = "baz") {…}
becomes:
func foo<T: ExpressibleByStringLiteral>(bar: T = "baz") {…}

As I understood it, omitting the type would work identically to `let` declarations. A string literal without a type defaults to `String`. Treating it as a generic function is a bad idea IMO.

More specifically, a string literal without a type defaults to the StringLiteralType typealias:

typealias StringLiteralType = StaticString
let s = "abc"
print(type(of: s))
// prints StaticString

What version of the Swift compiler are you using? I don’t observe this behavior. That code prints `String` for me.

···

On Mar 11, 2017, at 3:22 PM, Ben Cohen <ben_cohen@apple.com> wrote:

On Mar 11, 2017, at 1:17 PM, Jaden Geller via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
On Mar 11, 2017, at 12:20 PM, David Sweeris via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I don't think this sugar is worth any amount of added complexity. Most function arguments will have not have default values and this have to continue to declare the type, so this would only be more concise in very few cases. I'd prefer the consistency of always having to explicitly declare the argument type at a function boundary.

To call a function, you need to know what type to pass in. This becomes more difficult when not make explicit, particularly when a more complicated expression is used as a default. -1

Is there anything we can do with a variable, if all we know of it is that it conforms to `ExpressibleByStringLiteral`? I can’t think of anything… If we had a way to get back the literal string which the variable was initialized with, we could initialize other values with that, but the protocol doesn’t require us to store it. Come to think of it, is there even a way to store a literal value in its “untyped” form? You can declare a variable to of type `IntegerLiteralType`, but the type system then treats it as an `Int`.

So while it looks nice (to me, anyway) I’m not sure you could actually do anything with it. Or am I looking at this wrong?

- Dave Sweeris
_______________________________________________
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 <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Robert Widmann) #17

You may be missing/misspelling the typealias declaration. This has been in Policy.swift for a while now, and I can reproduce this as far back as 2.2 in the Bluemix sandbox.

~Robert Widmann

···

On Mar 11, 2017, at 7:41 PM, Jaden Geller via swift-evolution <swift-evolution@swift.org> wrote:

On Mar 11, 2017, at 3:22 PM, Ben Cohen <ben_cohen@apple.com <mailto:ben_cohen@apple.com>> wrote:

On Mar 11, 2017, at 1:17 PM, Jaden Geller via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 11, 2017, at 12:20 PM, David Sweeris via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

-1

It would be inconsistent to allow it for deterministic literals (String) and not for non deterministic literal (int which can be either a Int, Uint, Float, …)

If I’m not mistaken, even with `bar = “baz”`, `String` is merely the default inferred type. It could be anything that conforms to `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a way to make a function implicitly generic:
func foo(bar = "baz") {…}
becomes:
func foo<T: ExpressibleByStringLiteral>(bar: T = "baz") {…}

As I understood it, omitting the type would work identically to `let` declarations. A string literal without a type defaults to `String`. Treating it as a generic function is a bad idea IMO.

More specifically, a string literal without a type defaults to the StringLiteralType typealias:

typealias StringLiteralType = StaticString
let s = "abc"
print(type(of: s))
// prints StaticString

What version of the Swift compiler are you using? I don’t observe this behavior. That code prints `String` for me.

I don't think this sugar is worth any amount of added complexity. Most function arguments will have not have default values and this have to continue to declare the type, so this would only be more concise in very few cases. I'd prefer the consistency of always having to explicitly declare the argument type at a function boundary.

To call a function, you need to know what type to pass in. This becomes more difficult when not make explicit, particularly when a more complicated expression is used as a default. -1

Is there anything we can do with a variable, if all we know of it is that it conforms to `ExpressibleByStringLiteral`? I can’t think of anything… If we had a way to get back the literal string which the variable was initialized with, we could initialize other values with that, but the protocol doesn’t require us to store it. Come to think of it, is there even a way to store a literal value in its “untyped” form? You can declare a variable to of type `IntegerLiteralType`, but the type system then treats it as an `Int`.

So while it looks nice (to me, anyway) I’m not sure you could actually do anything with it. Or am I looking at this wrong?

- Dave Sweeris
_______________________________________________
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 <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


(Jaden Geller) #18

Ahh, misunderstanding then. I had thought they were suggesting this was the default value of the typealias.

Thanks for clearing that up,
Jaden Geller

···

On Mar 11, 2017, at 5:08 PM, Robert Widmann <devteam.codafi@gmail.com> wrote:

You may be missing/misspelling the typealias declaration. This has been in Policy.swift for a while now, and I can reproduce this as far back as 2.2 in the Bluemix sandbox.

~Robert Widmann

On Mar 11, 2017, at 7:41 PM, Jaden Geller via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 11, 2017, at 3:22 PM, Ben Cohen <ben_cohen@apple.com <mailto:ben_cohen@apple.com>> wrote:

On Mar 11, 2017, at 1:17 PM, Jaden Geller via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 11, 2017, at 12:20 PM, David Sweeris via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

-1

It would be inconsistent to allow it for deterministic literals (String) and not for non deterministic literal (int which can be either a Int, Uint, Float, …)

If I’m not mistaken, even with `bar = “baz”`, `String` is merely the default inferred type. It could be anything that conforms to `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a way to make a function implicitly generic:
func foo(bar = "baz") {…}
becomes:
func foo<T: ExpressibleByStringLiteral>(bar: T = "baz") {…}

As I understood it, omitting the type would work identically to `let` declarations. A string literal without a type defaults to `String`. Treating it as a generic function is a bad idea IMO.

More specifically, a string literal without a type defaults to the StringLiteralType typealias:

typealias StringLiteralType = StaticString
let s = "abc"
print(type(of: s))
// prints StaticString

What version of the Swift compiler are you using? I don’t observe this behavior. That code prints `String` for me.

I don't think this sugar is worth any amount of added complexity. Most function arguments will have not have default values and this have to continue to declare the type, so this would only be more concise in very few cases. I'd prefer the consistency of always having to explicitly declare the argument type at a function boundary.

To call a function, you need to know what type to pass in. This becomes more difficult when not make explicit, particularly when a more complicated expression is used as a default. -1

Is there anything we can do with a variable, if all we know of it is that it conforms to `ExpressibleByStringLiteral`? I can’t think of anything… If we had a way to get back the literal string which the variable was initialized with, we could initialize other values with that, but the protocol doesn’t require us to store it. Come to think of it, is there even a way to store a literal value in its “untyped” form? You can declare a variable to of type `IntegerLiteralType`, but the type system then treats it as an `Int`.

So while it looks nice (to me, anyway) I’m not sure you could actually do anything with it. Or am I looking at this wrong?

- Dave Sweeris
_______________________________________________
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 <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution