Should Version be StringLiteralConvertible?


(Ling Wang) #1

Because Version.init?(_ characters:) is really failable this code is very dangerous:
extension Version: StringLiteralConvertible {
    public init(stringLiteral value: String) {
        self.init(value.characters)!
    }

Is the convenience worth it?


(Max Howell) #2

Can you provide a use case that demonstrates the danger?

I can only imagine situations where the Package.swift is invalid and thus `swift build` simply errors out. No data is lost, no work is lost. Just time.

···

On Dec 30, 2015, at 1:16 PM, Ling Wang via swift-build-dev <swift-build-dev@swift.org> wrote:

Because Version.init?(_ characters:) is really failable this code is very dangerous:
extension Version: StringLiteralConvertible {
   public init(stringLiteral value: String) {
       self.init(value.characters)!
   }

Is the convenience worth it?
_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-build-dev


(Ling Wang) #3

I guess there is not real consequence in the current code base. But it potentially lets us write crashing code like this without any help from the type system because we explicitly disabled the protection:

let version: Version = “hello”

By contrast, if Version is not StringLiteralConvertible, we must write code like this:

let version: Version = Version(“hello”)

where the type system will catch the error and force us to explicitly handle the potential `nil` result:

value of optional type 'Version?' not unwrapped; did you mean to use '!' or '?'?

···

On Jan 4, 2016, at 1:22 PM, Max Howell <max.howell@apple.com> wrote:

Can you provide a use case that demonstrates the danger?

I can only imagine situations where the Package.swift is invalid and thus `swift build` simply errors out. No data is lost, no work is lost. Just time.

On Dec 30, 2015, at 1:16 PM, Ling Wang via swift-build-dev <swift-build-dev@swift.org> wrote:

Because Version.init?(_ characters:) is really failable this code is very dangerous:
extension Version: StringLiteralConvertible {
  public init(stringLiteral value: String) {
      self.init(value.characters)!
  }

Is the convenience worth it?
_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-build-dev


(Max Howell) #4

I guess there is not real consequence in the current code base. But it potentially lets us write crashing code like this without any help from the type system because we explicitly disabled the protection:

let version: Version = “hello”

By contrast, if Version is not StringLiteralConvertible, we must write code like this:

let version: Version = Version(“hello”)

where the type system will catch the error and force us to explicitly handle the potential `nil` result:

value of optional type 'Version?' not unwrapped; did you mean to use '!' or '?’?

Well there’s two things:

1. If done in a Package.swift it will fail to build. Which is good. We want it to fail to build if the version is invalid.
2. We don’t use this constructor in the Package Manager’s sources, for the reasons you specify.


(Ling Wang) #5

Yes, as I said, I think there is no real consequence in current code. Just potential misusing danger in future. I suggest we use the help and protection of the type system as much as we can. That’s all.

···

On Jan 4, 2016, at 4:49 PM, Max Howell <max.howell@apple.com> wrote:

I guess there is not real consequence in the current code base. But it potentially lets us write crashing code like this without any help from the type system because we explicitly disabled the protection:

let version: Version = “hello”

By contrast, if Version is not StringLiteralConvertible, we must write code like this:

let version: Version = Version(“hello”)

where the type system will catch the error and force us to explicitly handle the potential `nil` result:

value of optional type 'Version?' not unwrapped; did you mean to use '!' or '?’?

Well there’s two things:

1. If done in a Package.swift it will fail to build. Which is good. We want it to fail to build if the version is invalid.
2. We don’t use this constructor in the Package Manager’s sources, for the reasons you specify.