Re: [swift-users] ⁨Is it possible to store a set of heterogeneous items with protocol?

2017-07-18 Thread Glen Huang via swift-users
Do you think if there will be any evolution proposal to address this 
limitation? Or it’s an inherent tradeoff that is unlikely to be changed?

> On 19 Jul 2017, at 8:49 AM, Jordan Rose  wrote:
> 
> 
> 
>> On Jul 18, 2017, at 10:33, Vladimir.S via swift-users > > wrote:
>> 
>> On 17.07.2017 4:51, Glen Huang via swift-users wrote:
>>> Thanks for the code sample and link, but if I’m not wrong, this pattern 
>>> doesn’t allow heterogeneous items.
>> 
>> Support the question. Trying to understand if we can have something like 
>> [AnyHashable] for our custom protocol(with associated type) or AnyHashable 
>> has a very special support from compiler and we can use only [Any] or such 
>> kind of wrapper:
>> 
>> struct AnyMyProtocol {
>>  let actualInstance: Any
>>  init(_ instance: T) { actualInstance = instance}
>> }
>> 
>> let instances: [AnyMyProtocol] = [AnyMyProtocol(...), AnyMyProtocol(...)]
>> 
>> if let some = instances[0].actualInstance as? 
>> SpecificImplementationOfMyProtocol {
>>  // use 'some' as SpecificImplementationMyProtocol instance
>>  // seems like no way to refer to just MyProtocol
>> }
> 
> AnyHashable is special, sorry. You'll have to use this sort of indirect 
> unwrapping instead. You can write a little convenience method for it though, 
> if you want:
> 
> extension AnyMyProtocol {
>   func get(as: T.Type) -> T? {
> return self.actualInstance as? T
>   }
> }
> 
> if let some = instances[0].get(as: SpecificImplementationOfMyProtocol.self) {
>   // use 'some' here
> }
> 
> Jordan

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] matching a protocol value in multiple patterns is not yet supported; use separate cases instead

2017-07-18 Thread Zhao Xin via swift-users
I encounter this error today. "matching a protocol value in multiple
patterns is not yet supported; use separate cases instead"

Sample code:

import Foundation


protocol NameProtocol {

var name:String { get }

}


struct Cat:NameProtocol {

let name:String

}


struct Dog:NameProtocol {

let name: String

}


enum AnimalType {

case catType(cat:NameProtocol)

case dogType(dog:NameProtocol)

}


struct Animal {

let type:AnimalType



func printName() {

switch type {

case .catType(let animal), // matching a protocol value in multiple
patterns is not yet supported; use separate cases instead

.dogType(let animal):

print(animal.name)

}

}

}


let cat = Cat(name: "kitty")

let catType = AnimalType.catType(cat: cat)

let animal = Animal(type: catType)

animal.printName()


I am wondering which proposal this is? And will it be implemented in Swift
4.0? I search the error as keywords, but didn't get the expected results.

Zhao Xin
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Convenience initializers in structs?

2017-07-18 Thread Chris McIntyre via swift-users
Was it ever explained why the syntax is different?

--
Chris McIntyre

> On Jul 18, 2017, at 6:46 PM, Jens Persson via swift-users 
>  wrote:
> 
> That is not true. Structs can have delegating initializers but they cannot be 
> marked with `convenience` (only the initializers of class types can).
> 
> This is very clear from both the documentation and the compiler:
> 
> (1) The Swift Programming language (Swift 4):
> "Swift defines two kinds of initializers for *class* types to help ensure all 
> stored properties receive an initial value. These are known as designated 
> initializers and convenience initializers."
> 
> (2) The compiler:
> 
> struct S {
> var a, b: Int
> init(_ a: Int, _ b: Int) {
> self.a = a
> self.b = b
> }
> convenience init(_ ab: Int) { // <-- Error
> self.init(ab, ab)
> }
> }
> The error message is:
> Delegating initializers in structs are not marked with 'convenience'
> The suggested fix is to remove the word convenience.
> 
> Please reread my previous post, perform the steps I describe (looking at 
> Quick Help, also try jump to definition for that `init` and you'll see it is 
> marked with `convenience` even though it is in a struct), also look at the 
> link to the documentation for the Int init, it too is marked with 
> convenience, even though Int is a struct.
> 
> /Jens
> 
> 
>> On Tue, Jul 18, 2017 at 9:46 PM, Slava Pestov  wrote:
>> Hi Jens,
>> 
>> While I’m not familiar with the integer API in the standard library, structs 
>> and enums certainly can have convenience initializers. They must delegate to 
>> another initializer (either convenience or designated) rather than 
>> initializing the fields of the type one by one.
>> 
>> Slava
>> 
>>> On Jul 18, 2017, at 6:46 AM, Jens Persson via swift-users 
>>>  wrote:
>>> 
>>> Start a command line project in Xcode 9 beta 3 and copy paste this single 
>>> line of code into main.swift
>>> 
>>> let _ = UInt8.init(extendingOrTruncating: UInt64(123456))
>>> 
>>> Now look at Quick Help while placing the cursor on `init` and then on 
>>> `extendingOrTruncating`.
>>> 
>>> Note that (and how) the documentation for the initializer differs depending 
>>> on where you place the cursor.
>>> 
>>> If the cursor is on `init`, the initializer is shown to be a convenience(!) 
>>> initializer even though structs (such as UInt8) cannot have convenience 
>>> initializers, right?
>>> 
>>> Even the official documentation for this and several other initializer like 
>>> eg:
>>> https://developer.apple.com/documentation/swift/int/2885075-init
>>> clearly shows convenience initializers in structs.
>>> 
>>> By the way, .init(extendingOrTruncating:) doesn't show in the list of 
>>> completions for "UInt8.init" but it does for "UInt8(".
>>> 
>>> 
>>> Can anyone explain what's going on?
>>> 
>>> Are these known issues that will go away in time for Xcode 9 GM?
>>> 
>>> /Jens
>>> 
>>> ___
>>> swift-users mailing list
>>> swift-users@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>> 
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Convenience initializers in structs?

2017-07-18 Thread Slava Pestov via swift-users
Hi Jens,

While I’m not familiar with the integer API in the standard library, structs 
and enums certainly can have convenience initializers. They must delegate to 
another initializer (either convenience or designated) rather than initializing 
the fields of the type one by one.

Slava

> On Jul 18, 2017, at 6:46 AM, Jens Persson via swift-users 
>  wrote:
> 
> Start a command line project in Xcode 9 beta 3 and copy paste this single 
> line of code into main.swift
> 
> let _ = UInt8.init(extendingOrTruncating: UInt64(123456))
> 
> Now look at Quick Help while placing the cursor on `init` and then on 
> `extendingOrTruncating`.
> 
> Note that (and how) the documentation for the initializer differs depending 
> on where you place the cursor.
> 
> If the cursor is on `init`, the initializer is shown to be a convenience(!) 
> initializer even though structs (such as UInt8) cannot have convenience 
> initializers, right?
> 
> Even the official documentation for this and several other initializer like 
> eg:
> https://developer.apple.com/documentation/swift/int/2885075-init 
> 
> clearly shows convenience initializers in structs.
> 
> By the way, .init(extendingOrTruncating:) doesn't show in the list of 
> completions for "UInt8.init" but it does for "UInt8(".
> 
> 
> Can anyone explain what's going on?
> 
> Are these known issues that will go away in time for Xcode 9 GM?
> 
> /Jens
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] What is up with names not being Strings any more in Swift 4?

2017-07-18 Thread Jon Shier via swift-users
I'd agree with that. Fortunately there are tools out there that can parse such 
things and generate the constants for us already. Waiting for Xcode to 
implement such common sense quality of life improvements probably won't end. 
I'll file bugs in the meantime though. 


Jon

> On Jul 18, 2017, at 1:38 PM, Hooman Mehr via swift-users 
>  wrote:
> 
> I think this should be a feature of Xcode to automatically generate / 
> maintain these constants: When you add assets or create interface builder 
> files, a plug-in could take care of generating / updating such constants and 
> you would get auto-complete and type safety for free.
> 
>> On Jul 18, 2017, at 3:56 AM, Manfred Schubert via swift-users 
>>  wrote:
>> 
>> 
>>> Am 18.07.2017 um 00:58 schrieb Greg Parker via swift-users 
>>> :
>>> 
>>> 
 On Jul 17, 2017, at 10:01 AM, Nevin Brackett-Rozinsky via swift-users 
  wrote:
 
 Could / should these types be ExpressibleByStringLiteral?
>>> 
>>> They should not. We are deliberately discouraging the string literal of the 
>>> name. The string literal should be in only one place: the definition of the 
>>> name constant. Everything else should use the constant. The compiler can 
>>> provide autocompletion and typo detection of the constant. The string 
>>> literal doesn't get that.
>> 
>> The thing is, with Notification.Name, you have to use them at least twice. 
>> So everybody is creating a constant. And typos in the String that defines 
>> the constant don't matter. So this solves the problem. With NSNib however, 
>> the default case is to use the name only once. And I would say with NSImage 
>> it's probably the same. I don't think people have been defining constants 
>> for these when they are only used once. It makes the code unnecessarily 
>> longer and more complicated. And a typo in the String that defines the 
>> constant matter just as much as a typo in the String literal. So in the 
>> default case this doesn't solve a problem.
>> 
>> 
>> Kind regards,
>> 
>> Manfred
>> ___
>> swift-users mailing list
>> swift-users@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] What is up with names not being Strings any more in Swift 4?

2017-07-18 Thread Hooman Mehr via swift-users
I think this should be a feature of Xcode to automatically generate / maintain 
these constants: When you add assets or create interface builder files, a 
plug-in could take care of generating / updating such constants and you would 
get auto-complete and type safety for free.

> On Jul 18, 2017, at 3:56 AM, Manfred Schubert via swift-users 
>  wrote:
> 
> 
>> Am 18.07.2017 um 00:58 schrieb Greg Parker via swift-users 
>> :
>> 
>> 
>>> On Jul 17, 2017, at 10:01 AM, Nevin Brackett-Rozinsky via swift-users 
>>>  wrote:
>>> 
>>> Could / should these types be ExpressibleByStringLiteral?
>> 
>> They should not. We are deliberately discouraging the string literal of the 
>> name. The string literal should be in only one place: the definition of the 
>> name constant. Everything else should use the constant. The compiler can 
>> provide autocompletion and typo detection of the constant. The string 
>> literal doesn't get that.
> 
> The thing is, with Notification.Name, you have to use them at least twice. So 
> everybody is creating a constant. And typos in the String that defines the 
> constant don't matter. So this solves the problem. With NSNib however, the 
> default case is to use the name only once. And I would say with NSImage it's 
> probably the same. I don't think people have been defining constants for 
> these when they are only used once. It makes the code unnecessarily longer 
> and more complicated. And a typo in the String that defines the constant 
> matter just as much as a typo in the String literal. So in the default case 
> this doesn't solve a problem.
> 
> 
> Kind regards,
> 
> Manfred
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] ⁨Is it possible to store a set of heterogeneous items with protocol?

2017-07-18 Thread Vladimir.S via swift-users

On 17.07.2017 4:51, Glen Huang via swift-users wrote:
Thanks for the code sample and link, but if I’m not wrong, this pattern doesn’t allow 
heterogeneous items.


Support the question. Trying to understand if we can have something like 
[AnyHashable] for our custom protocol(with associated type) or AnyHashable has a very 
special support from compiler and we can use only [Any] or such kind of wrapper:


struct AnyMyProtocol {
  let actualInstance: Any
  init(_ instance: T) { actualInstance = instance}
}

let instances: [AnyMyProtocol] = [AnyMyProtocol(...), AnyMyProtocol(...)]

if let some = instances[0].actualInstance as? 
SpecificImplementationOfMyProtocol {
// use 'some' as SpecificImplementationMyProtocol instance
// seems like no way to refer to just MyProtocol
}




If I have these definitions:

struct Chicken {}
struct Pig {}

class ChickenFarm: Farm {
 func grow() -> Chicken {
 return Chicken()
 }
}

class PigFarm: Farm {
 func grow() -> Pig {
 return Pig()
 }
}

Then:

var farms = // How do I define a set that can contain both ChickenFarm and 
PigFarm?
farms.insert(AnyFarm(ChickenFarm()))
farms.insert(AnyFarm(PigFarm()))


On 17 Jul 2017, at 4:02 AM, Nevin Brackett-Rozinsky 
> wrote:


The standard pattern for type-erasure in Swift looks like this:

protocol Farm {
associatedtype Produce
func grow() -> Produce
}

private class _AnyFarmBase : Farm {
func grow() -> T { fatalError() }
}

private final class _AnyFarmBox: _AnyFarmBase {
var farm: U
init(_ x: U) { farm = x }
override func grow() -> U.Produce {
return farm.grow()
}
}

public final class AnyFarm : Farm {
private let wrapped: _AnyFarmBase
func grow() -> V { return wrapped.grow() }
init (_ x: W) where W.Produce == V {
wrapped = _AnyFarmBox(x)
}
}


There is one little hiccough when you need an initializer in the abstract base 
class, which you can read about here 
 among 
other places.


Hope that helps,

Nevin


On Sun, Jul 16, 2017 at 12:32 AM, Glen Huang via swift-users > wrote:


This sounds like the right approach!

However, as I experimented with AnyHashable more, I found out that after
converting a concrete type to it, I could still convert back using “as”:

AnyHashable(Foo()) as! Foo

I guess that’s not the case with AnyNamed? I tried to imitate AnyHashable:

struct AnyNamed: Named {
let base: Any
init(_ value: T) {
base = value
}

var name: String {
// How do I convert `base` to `Named` here?
}
}

But I have no idea what to put in `var name: String`. Also, even if we 
managed
to come up with a solution, would it magically allow direct casting with 
“as”?
Does the complier do something special for AnyHashable?


> On 16 Jul 2017, at 12:58 AM, Ole Begemann > wrote:
>
> One way to do this in Swift is a method called type erasure.
>
> Type erasure means you create a new type that wraps any value whose 
concrete
type you want to erase. This new type also conforms to the protocol. By
convention the type is named Any... (compare AnyIterator and AnySequence in 
the
standard library, which do the same thing).
>
> struct AnyNamed: Named {
>private let _name: () -> String
>
>init(_ value: T) {
>_name = { value.name  }
>}
>
>var name: String {
>return _name()
>}
> }
>
> AnyNamed is initialized with a generic value T: Named. Notice that the
initializer is generic, but the type itself isn't. Because AnyNamed can't 
store
value: T directly (then it would have to be generic over T), we create a
closure over value.name  and store that instead.
>
> Now we can create a Set and, because AnyNamed conforms to Named,
treat the set's elements as values conforming to Named:
>
> var set = Set()
> set.insert(AnyNamed(Foo()))
> set.insert(AnyNamed(Bar()))
>
> for element in set {
>print(element.name )
>print(element.hashValue)
> }
>
>
> On 11.07.2017 12:10, Glen Huang via swift-users wrote:
>> Hi,
>>
>> I want to store some heterogeneous items all conform to a protocol 
inside a
set, is it something possible to do in swift?
>>
>> I tried this example:
>>
>> ```
>> protocol Named: Hashable {
>>var name: String { get }
>> }
>>
>> extension Named {
>>var hashValue: Int {
>>return name.hashValue
>>}
>>
>>static func ==(lhs: Self, rhs: Self) -> Bool {
>>   

[swift-users] Convenience initializers in structs?

2017-07-18 Thread Jens Persson via swift-users
Start a command line project in Xcode 9 beta 3 and copy paste this single
line of code into main.swift

let _ = UInt8.init(extendingOrTruncating: UInt64(123456))

Now look at Quick Help while placing the cursor on `init` and then on
`extendingOrTruncating`.

Note that (and how) the documentation for the initializer differs depending
on where you place the cursor.

If the cursor is on `init`, the initializer is shown to be a convenience(!)
initializer even though structs (such as UInt8) cannot have convenience
initializers, right?

Even the official documentation for this and several other initializer like
eg:
https://developer.apple.com/documentation/swift/int/2885075-init
clearly shows convenience initializers in structs.

By the way, .init(extendingOrTruncating:) doesn't show in the list of
completions for "UInt8.init" but it does for "UInt8(".


Can anyone explain what's going on?

Are these known issues that will go away in time for Xcode 9 GM?

/Jens
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] What is up with names not being Strings any more in Swift 4?

2017-07-18 Thread Manfred Schubert via swift-users

> Am 18.07.2017 um 00:58 schrieb Greg Parker via swift-users 
> :
> 
> 
>> On Jul 17, 2017, at 10:01 AM, Nevin Brackett-Rozinsky via swift-users 
>>  wrote:
>> 
>> Could / should these types be ExpressibleByStringLiteral?
> 
> They should not. We are deliberately discouraging the string literal of the 
> name. The string literal should be in only one place: the definition of the 
> name constant. Everything else should use the constant. The compiler can 
> provide autocompletion and typo detection of the constant. The string literal 
> doesn't get that.

The thing is, with Notification.Name, you have to use them at least twice. So 
everybody is creating a constant. And typos in the String that defines the 
constant don't matter. So this solves the problem. With NSNib however, the 
default case is to use the name only once. And I would say with NSImage it's 
probably the same. I don't think people have been defining constants for these 
when they are only used once. It makes the code unnecessarily longer and more 
complicated. And a typo in the String that defines the constant matter just as 
much as a typo in the String literal. So in the default case this doesn't solve 
a problem.


Kind regards,

Manfred
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users