> On Mar 13, 2017, at 11:50 AM, John McCall <[email protected]> wrote:
>
>> On Mar 12, 2017, at 5:00 PM, Matthew Johnson via swift-evolution
>> <[email protected] <mailto:[email protected]>> wrote:
>>> On Mar 12, 2017, at 3:23 PM, Karl Wagner <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>>
>>>> On 12 Mar 2017, at 14:32, Matthew Johnson <[email protected]
>>>> <mailto:[email protected]>> wrote:
>>>>
>>>> This is a really important feature IMO, but as others have pointed out it
>>>> basically amounts to higher-kinded types. I would love to be wrong about
>>>> this but I am reasonably sure this is out of scope for Swift 4 (otherwise
>>>> I would be working on a proposal already).
>>>>
>>>> Sent from my iPad
>>>>
>>>
>>> I’m not an expert on this stuff, but are they still higher-kinded types if
>>> we don’t express a relationship between Self and the associated type? I
>>> don’t think it’s quite the same conceptual leap as HKT.
>>
>> I’m no expert either but it sure seems to me like it enables the things
>> usually discussed in the context of higher-kinder types. Maybe someone from
>> the core team can comment on whether there is a meaningful difference
>
> Yes, it's a way of getting some of the behavior of higher-kinded types. Kind
> of a well-known trick in a number of languages. It's significantly simpler
> to handle in the type system because the higher-kinded entities stay "second
> class" — you don't necessarily have to deal with, say, higher-kinded type
> variables in the constraint solver or in type inference. Of course, that
> limits some of the code you can write, or at least the simplicity of that
> code.
Interesting, thanks John. This would solve many of the use cases I have in
mind. It’s good to know there is a solution that doesn’t require the full
complexity of higher-kinded types. Maybe it will be feasible sooner than full
HKT.
>
>> and whether this is something that could fit into Swift 4.
>
> No.
That’s what I suspected. Thanks for confirming.
>
> John.
>
>>
>>>
>>> Consider that every associated type must be backed by a typealias (explicit
>>> or inferred) in the conforming type. We can already have generic
>>> typealiases. This would be a more targeted thing which required those
>>> associatedtype-implementing-typealiases to contain generic parameters. It
>>> would also extend the constraints from SE-0142 to allow constraints to
>>> refer to those parameters and bind them to other associated types.
>>>
>>> The workaround is basically to erase and dynamic-cast your way out:
>>
>> Yes, there are workarounds, none of which are desirable.
>>
>> I ran into a case last year where there was a significant performance impact
>> caused by the need to perform type erasure as a workaround. The type
>> erasing wrapper required an allocation and type information that could have
>> been used by the optimizer was lost. This was frustrating and convinced me
>> that we definitely need HKT in Swift eventually. There are very useful
>> generic libraries that cannot be implemented efficiently without them.
>>
>>
>>>
>>> //NOTE: dynamic type of ScanPromise.Result *must* be same as closure
>>> result. No static enforcement though :(
>>>
>>> extension Scanner where ScanPromise.Result == Any? {
>>> func scan<T>(from f: Offset, until u: (Offset, Item) -> T?) -> T? {
>>> return withoutActuallyEscaping(u) { _u -> T? in
>>> return promiseScan(from: f, until: _u).await() as? T // downcast
>>> from Any? to T?
>>> }
>>> }
>>> }
>>>
>>> class MyPromise<R>: Promise {
>>> typealias Result = R?
>>> let offset: Offset
>>> let block: (Offset, Item) -> R?
>>> }
>>>
>>> class MyScanner: Scanner {
>>> typealias ScanPromise = MyPromise<Any> // want this to be “typealias
>>> ScanPromise<X> = MyPromise<X>"
>>>
>>> func promiseScan<T>(from: Offset, until: @escaping (Offset, Item) ->
>>> T?) -> ScanPromise {
>>> return MyPromise(offset: from, block: until) // upcast from T? to
>>> Any?
>>> }
>>> }
>>>
>>> - Karl
>>>
>>>> On Mar 11, 2017, at 11:49 PM, Karl Wagner via swift-evolution
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>
>>>>> I have a model like this:
>>>>>
>>>>> protocol Promise {
>>>>> associatedtype Result
>>>>> }
>>>>>
>>>>> protocol Scanner {
>>>>> associatedtype ScanPromise: Promise
>>>>>
>>>>> func promiseScan<T>(from: Offset, until: (Offset, Item) -> T?) ->
>>>>> ScanPromise // where Result == T?
>>>>> }
>>>>>
>>>>> The thing that I’m trying to express is: whichever type implements the
>>>>> associated type ‘ScanPromise’ must be generic, and that parameter must be
>>>>> its result (i.e. something it got as a result of calling the “until”
>>>>> closure).
>>>>>
>>>>> Even with SE-0142, this kind of constraint would not be possible. What I
>>>>> would like to write is something like this:
>>>>>
>>>>> protocol Promise {
>>>>> associatedtype Result
>>>>> }
>>>>>
>>>>> protocol Scanner {
>>>>> associatedtype ScanPromise<T>: Promise // now generic. [SE-0142]:
>>>>> where Result == T
>>>>>
>>>>> func promiseScan<T>(from: Offset, until: (Offset, Item) -> T?) ->
>>>>> ScanPromise<T>
>>>>> }
>>>>>
>>>>> Thoughts?
>>>>>
>>>>> - Karl
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> [email protected] <mailto:[email protected]>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution