Re: [swift-users] Quick Question about ExpressibleByStringLiteral

2017-03-09 Thread David Sweeris via swift-users
Great! Thanks, Andrew :-)

- Dave Sweeris

> On Mar 9, 2017, at 6:00 PM, Jordan Rose  wrote:
> 
> Andrew Bennett is two steps ahead of you. :-) 
> https://github.com/apple/swift/pull/7125 
> 
> 
> Jordan
> 
>> On Mar 9, 2017, at 17:59, David Sweeris via swift-users 
>> mailto:swift-users@swift.org>> wrote:
>> 
>> If my type doesn’t know/care about the difference between a normal “String" 
>> and an “ExtendedClusterScalarGraphemeLiteralUnicodeTypeCluster” (or whatever 
>> those other literal types are called), is there anything wrong with doing 
>> this?
>> public protocol EasilyExpressibleByStringLiteral : 
>> ExpressibleByStringLiteral {
>> typealias StringLiteralType = String
>> }
>> extension EasilyExpressibleByStringLiteral where StringLiteralType == String 
>> {
>> public init(unicodeScalarLiteral value: String.UnicodeScalarLiteralType) 
>> {
>> self.init(stringLiteral: String(describing: value))
>> }
>> public init(extendedGraphemeClusterLiteral value: 
>> String.ExtendedGraphemeClusterLiteralType) {
>> self.init(stringLiteral: String(describing: value))
>> }
>> }
>> because then I only have to write the one init function:
>> public struct MyType : EasilyExpressibleByStringLiteral {
>> public init(stringLiteral value: StringLiteralType) {...}
>> }
>> and the compiler will stop complaining about my type not conforming to the 
>> other two protocols. Because I’ve scanned the docs, and I can’t even figure 
>> out how to create an ExtendedGraphemeClusterLiteral, let alone come up with 
>> a reason why I’d want to treat it differently than a regular String when 
>> using it to initialize an instance of MyType.
>> 
>> - Dave Sweeris
>> ___
>> 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] Quick Question about ExpressibleByStringLiteral

2017-03-09 Thread Jordan Rose via swift-users
Andrew Bennett is two steps ahead of you. :-) 
https://github.com/apple/swift/pull/7125 


Jordan

> On Mar 9, 2017, at 17:59, David Sweeris via swift-users 
>  wrote:
> 
> If my type doesn’t know/care about the difference between a normal “String" 
> and an “ExtendedClusterScalarGraphemeLiteralUnicodeTypeCluster” (or whatever 
> those other literal types are called), is there anything wrong with doing 
> this?
> public protocol EasilyExpressibleByStringLiteral : ExpressibleByStringLiteral 
> {
> typealias StringLiteralType = String
> }
> extension EasilyExpressibleByStringLiteral where StringLiteralType == String {
> public init(unicodeScalarLiteral value: String.UnicodeScalarLiteralType) {
> self.init(stringLiteral: String(describing: value))
> }
> public init(extendedGraphemeClusterLiteral value: 
> String.ExtendedGraphemeClusterLiteralType) {
> self.init(stringLiteral: String(describing: value))
> }
> }
> because then I only have to write the one init function:
> public struct MyType : EasilyExpressibleByStringLiteral {
> public init(stringLiteral value: StringLiteralType) {...}
> }
> and the compiler will stop complaining about my type not conforming to the 
> other two protocols. Because I’ve scanned the docs, and I can’t even figure 
> out how to create an ExtendedGraphemeClusterLiteral, let alone come up with a 
> reason why I’d want to treat it differently than a regular String when using 
> it to initialize an instance of MyType.
> 
> - Dave Sweeris
> ___
> 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] Quick Question about ExpressibleByStringLiteral

2017-03-09 Thread David Sweeris via swift-users
If my type doesn’t know/care about the difference between a normal “String" and 
an “ExtendedClusterScalarGraphemeLiteralUnicodeTypeCluster” (or whatever those 
other literal types are called), is there anything wrong with doing this?
public protocol EasilyExpressibleByStringLiteral : ExpressibleByStringLiteral {
typealias StringLiteralType = String
}
extension EasilyExpressibleByStringLiteral where StringLiteralType == String {
public init(unicodeScalarLiteral value: String.UnicodeScalarLiteralType) {
self.init(stringLiteral: String(describing: value))
}
public init(extendedGraphemeClusterLiteral value: 
String.ExtendedGraphemeClusterLiteralType) {
self.init(stringLiteral: String(describing: value))
}
}
because then I only have to write the one init function:
public struct MyType : EasilyExpressibleByStringLiteral {
public init(stringLiteral value: StringLiteralType) {...}
}
and the compiler will stop complaining about my type not conforming to the 
other two protocols. Because I’ve scanned the docs, and I can’t even figure out 
how to create an ExtendedGraphemeClusterLiteral, let alone come up with a 
reason why I’d want to treat it differently than a regular String when using it 
to initialize an instance of MyType.

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


Re: [swift-users] Protocol conformance failure

2017-03-09 Thread Guillaume Lessard via swift-users

> On Mar 9, 2017, at 12:46, Edward Connell via swift-users 
>  wrote:
> 
> // Everything compiles fine until this
> someFunc(items: items)

This is a frequent pain point: protocol existentials cannot stand in for the 
protocol they represent.
Your function wants a concrete type that conforms to ItemProtocol, but an array 
of disparate types which happen to separately conform to ItemProtocol does not 
do that.

You will need to overload thusly:

func someFunc(items: [ItemProtocol]) {
  for item in items {
print(item.message)
  }
}

until, someday, this pain point is resolved.

Cheers,
Guillaume Lessard

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


[swift-users] Protocol conformance failure

2017-03-09 Thread Edward Connell via swift-users
The error says ItemProtocol does not conform to ItemProtocol.
That doesn't make sense. It seems this should work fine.

// It's all clean until the last line
protocol ItemProtocol : class {
var message: String { get }
}

// heterogenious types
class A : ItemProtocol {
var message = "A"
}

class B : ItemProtocol {
var message = "B"
}


var items: [ItemProtocol] = [A(), B()]

func someFunc(items: [T]) {
for item in items {
print(item.message)
}
}

// Everything compiles fine until this
someFunc(items: items)
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Unexpected results when using String.CharacterView.Index

2017-03-09 Thread Zhao Xin via swift-users
Thanks a lot, Ole. I understand now.

Zhaoxin

On Thu, Mar 9, 2017 at 7:54 PM, Ole Begemann  wrote:

> On 09/03/2017 08:27, Zhao Xin via swift-users wrote:
>
>> When using subscript of `String.CharacterView`, I got an unexpected error.
>>
>> fatal error: Can't form a Character from an empty String
>>
>> func test() {
>> let s = "Original Script:"
>> let cs = s.characters
>> //let startIndex = cs.startIndex
>> let nextIndex = "Original ?".characters.endIndex
>> let nextCharacter = cs[nextIndex]// above error
>> }
>>
>> test()
>>
>
> First of all, it's not guaranteed that an index derived from one string
> can be used to subscript another string. Don't rely on that.
>
> endIndex is also different, and this is why you're seeing a crash here.
> Let's inspect nextIndex with dump(nextIndex):
>
> ▿ Swift.String.CharacterView.Index
>   ▿ _base: Swift.String.UnicodeScalarView.Index
> - _position: 10
>   - _countUTF16: 0
>
> You see that _countUTF16 is 0, i.e. internally, String.CharacterView
> assigns its endIndex a length of 0 (in terms of UTF-16 code units). This is
> why it traps when you use the index for subscripting. The endIndex is not a
> valid index for subscripting, not for the string it was derived from and
> not for any other string.
>
> ​However, if I chose​ another way to get the nextIndex. It works.
>>
>> functest() {
>> let s = "Original Script:"
>> let cs = s.characters
>> let startIndex = cs.startIndex
>> //let nextIndex = "Original ?".characters.endIndex
>> let nextIndex01 = cs.index(startIndex, offsetBy: "Original
>> ?".characters.count)
>> let nextCharacter = cs[nextIndex01]
>> }
>>
>> test()
>>
>
> Here, dump(nextIndex01) prints this:
>
> ▿ Swift.String.CharacterView.Index
>   ▿ _base: Swift.String.UnicodeScalarView.Index
> - _position: 10
>   - _countUTF16: 1
>
> Notice that _countUTF16 is 1, so it looks like a valid index from the
> perspective of cs. But again, don't rely on this! The results of
> subscripting a collection with an index derived from another collection are
> undefined unless the collection explicitly documents otherwise.
>
> Further more, I compared the two `nextIndex`. They were equal.
>>
>> functest() {
>> let s = "Original Script:"
>> let cs = s.characters
>> let startIndex = cs.startIndex
>> let nextIndex = "Original ?".characters.endIndex
>> let nextIndex01 = cs.index(startIndex, offsetBy: "Original
>> ?".characters.count)
>> let nextCharacter = cs[nextIndex01]
>> print(nextIndex01 == nextIndex) // true
>> }
>>
>> test()
>>
>
> It looks like String.Index only takes the position into account to
> determine equality, not its _countUTF16. This makes sense for the way
> endIndex and index(_:offsetBy:) are implemented. After all, nextIndex and
> nextIndex01 _should be equal_. It would certainly be possible to implement
> it differently (where endIndex and index(_:offsetBy:) returned identical
> indices, including _countUTF16:) and I don't know why the stdlib team chose
> to do it this way (maybe performance?).
>
> In any case, much of this implementation may change with the work going
> into strings for Swift 4.
>
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Generics with variable argument lists

2017-03-09 Thread Rien via swift-users
Ah!, yes that would be perfect!

Many thanks!

Regards,
Rien

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





> On 09 Mar 2017, at 12:36, Ole Begemann  wrote:
> 
> On 09/03/2017 11:05, Rien via swift-users wrote:
>> I am trying to achieve the following:
>> 
>> enum FunctionResult {
>>  case success(T)
>>  case error(String)
>> }
>> 
>> func tester(test: (…) -> FunctionResult, onError: (String) -> T) -> T {
>>   …
>> }
>> 
>> The problem is of course the (…) that simply does not work.
>> 
>> I would like to use this generic with a variety of different signatures, 
>> i.e.:
>> 
>> let result1 = tester(test: myfunc1(param: 26) -> FunctionResult, 
>> onError: { … handle the error ... })
>> let result2 = tester(test: myfunc2(param: “A String") -> 
>> FunctionResult, onError: { … handle the error ... })
>> let result3 = tester(test: myfunc3(param: 26, param2: “String") -> 
>> FunctionResult, onError: { … handle the error ... })
>> 
>> Is this at all possible?
> 
> This should do it:
> 
>func tester(test: @autoclosure () -> FunctionResult,
>onError: (String) -> T) -> T {
>switch test() {
>case .success(let value): return value
>case .error(let error): return onError(error)
>}
>}
> 
> The insight is that you don't really want to pass a function in the first 
> parameter, but only the _result_ of that function call. The @autoclosure 
> attribute then makes sure that the expression you pass to tester is only 
> evaluated inside tester. You can leave it out if you want (if you do, replace 
> `switch test()` with `switch test`).

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


Re: [swift-users] Unexpected results when using String.CharacterView.Index

2017-03-09 Thread Ole Begemann via swift-users

On 09/03/2017 08:27, Zhao Xin via swift-users wrote:

When using subscript of `String.CharacterView`, I got an unexpected error.

fatal error: Can't form a Character from an empty String

func test() {
let s = "Original Script:"
let cs = s.characters
//let startIndex = cs.startIndex
let nextIndex = "Original ?".characters.endIndex
let nextCharacter = cs[nextIndex]// above error
}

test()


First of all, it's not guaranteed that an index derived from one string 
can be used to subscript another string. Don't rely on that.


endIndex is also different, and this is why you're seeing a crash here. 
Let's inspect nextIndex with dump(nextIndex):


▿ Swift.String.CharacterView.Index
  ▿ _base: Swift.String.UnicodeScalarView.Index
- _position: 10
  - _countUTF16: 0

You see that _countUTF16 is 0, i.e. internally, String.CharacterView 
assigns its endIndex a length of 0 (in terms of UTF-16 code units). This 
is why it traps when you use the index for subscripting. The endIndex is 
not a valid index for subscripting, not for the string it was derived 
from and not for any other string.



​However, if I chose​ another way to get the nextIndex. It works.

functest() {
let s = "Original Script:"
let cs = s.characters
let startIndex = cs.startIndex
//let nextIndex = "Original ?".characters.endIndex
let nextIndex01 = cs.index(startIndex, offsetBy: "Original
?".characters.count)
let nextCharacter = cs[nextIndex01]
}

test()


Here, dump(nextIndex01) prints this:

▿ Swift.String.CharacterView.Index
  ▿ _base: Swift.String.UnicodeScalarView.Index
- _position: 10
  - _countUTF16: 1

Notice that _countUTF16 is 1, so it looks like a valid index from the 
perspective of cs. But again, don't rely on this! The results of 
subscripting a collection with an index derived from another collection 
are undefined unless the collection explicitly documents otherwise.



Further more, I compared the two `nextIndex`. They were equal.

functest() {
let s = "Original Script:"
let cs = s.characters
let startIndex = cs.startIndex
let nextIndex = "Original ?".characters.endIndex
let nextIndex01 = cs.index(startIndex, offsetBy: "Original
?".characters.count)
let nextCharacter = cs[nextIndex01]
print(nextIndex01 == nextIndex) // true
}

test()


It looks like String.Index only takes the position into account to 
determine equality, not its _countUTF16. This makes sense for the way 
endIndex and index(_:offsetBy:) are implemented. After all, nextIndex 
and nextIndex01 _should be equal_. It would certainly be possible to 
implement it differently (where endIndex and index(_:offsetBy:) returned 
identical indices, including _countUTF16:) and I don't know why the 
stdlib team chose to do it this way (maybe performance?).


In any case, much of this implementation may change with the work going 
into strings for Swift 4.



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


Re: [swift-users] Generics with variable argument lists

2017-03-09 Thread Ole Begemann via swift-users

On 09/03/2017 11:05, Rien via swift-users wrote:

I am trying to achieve the following:

enum FunctionResult {
  case success(T)
  case error(String)
}

func tester(test: (…) -> FunctionResult, onError: (String) -> T) -> T {
   …
}

The problem is of course the (…) that simply does not work.

I would like to use this generic with a variety of different signatures, i.e.:

let result1 = tester(test: myfunc1(param: 26) -> FunctionResult, onError: 
{ … handle the error ... })
let result2 = tester(test: myfunc2(param: “A String") -> FunctionResult, 
onError: { … handle the error ... })
let result3 = tester(test: myfunc3(param: 26, param2: “String") -> 
FunctionResult, onError: { … handle the error ... })

Is this at all possible?


This should do it:

func tester(test: @autoclosure () -> FunctionResult,
onError: (String) -> T) -> T {
switch test() {
case .success(let value): return value
case .error(let error): return onError(error)
}
}

The insight is that you don't really want to pass a function in the 
first parameter, but only the _result_ of that function call. The 
@autoclosure attribute then makes sure that the expression you pass to 
tester is only evaluated inside tester. You can leave it out if you want 
(if you do, replace `switch test()` with `switch test`).


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


[swift-users] Generics with variable argument lists

2017-03-09 Thread Rien via swift-users
I am trying to achieve the following:

enum FunctionResult {
  case success(T)
  case error(String)
}

func tester(test: (…) -> FunctionResult, onError: (String) -> T) -> T {
   …
}

The problem is of course the (…) that simply does not work.

I would like to use this generic with a variety of different signatures, i.e.:

let result1 = tester(test: myfunc1(param: 26) -> FunctionResult, onError: 
{ … handle the error ... })
let result2 = tester(test: myfunc2(param: “A String") -> FunctionResult, 
onError: { … handle the error ... })
let result3 = tester(test: myfunc3(param: 26, param2: “String") -> 
FunctionResult, onError: { … handle the error ... })

Is this at all possible?

Regards,
Rien

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





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