I hate C++ generics. Just thought about sharing this.

> On 29 May 2016, at 9:00 am, Matthew Johnson via swift-evolution 
> <[email protected]> wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On May 29, 2016, at 1:22 AM, Austin Zheng <[email protected]> wrote:
>> 
>> Thank you for reading through the proposal! 
>> 
>>> On May 28, 2016, at 7:41 PM, Matthew Johnson <[email protected]> wrote:
>>> 
>>> These are some very good and clearly articulated examples.  Great work!  
>>> This section is important because variadics are somewhat complicated and it 
>>> is important to show people why we want them and what problems they can 
>>> solve.
>> 
>> Any more practical use cases you can come up with (preferably ones that are 
>> distinct from the few we have now) would be greatly appreciated.
>> 
>> My thinking is that it's best to keep the feature as described in this 
>> proposal as lightweight as possible, proposing only enough expressiveness so 
>> that most reasonable use cases can be expressed. There are two reasons for 
>> that:
>> 
>> - Design and implementation burden relative to benefit. This is not a 
>> top-priority feature in the manifesto, and will be competing with at least 
>> two or three other features for resources. It's also quite complicated, 
>> as-is. It will affect how Swift handles resilience. [*]
>> - This proposal should not become a variadic generics proposal with a 
>> half-thought-out compile time metaprogramming scheme hanging off it. What 
>> Swift gets in terms of macros, code generation, or compile-time expressions 
>> deserves a conversation of its own eventually.
> 
> Very much agree with the comments about compile time meta programming here.  
> I'm really looking forward to that but we can do far better than C++ here.  
> 
>> 
>> More concretely, D has a "static if" construct 
>> (https://dlang.org/variadic-function-templates.html). It looks really nice - 
>> you could write a n-arity function that generates a `print("Hello, 
>> Matthew")` only if its arity is 3. I'm sure there are many use cases for it. 
>> Is building something similar worth spending time for during the Swift 3.x 
>> timeframe? Probably not, especially if it could be implemented in the future 
>> and the existing variadic generic semantics seamlessly extended to work with 
>> it.
>> 
>>> 
>>>> 
>>>> There is a lot of scope for design refinements, and even for alternative 
>>>> designs. With enhanced existentials, there was already an informal 
>>>> consensus that the feature would involve composing some protocols and 
>>>> class requirements, and placing constraints on the associated types, and 
>>>> most everything else was working out the various implications of doing so. 
>>>> That's not true for this feature.
>>>> 
>>>> In particular, I'm interested to see if there are similarly expressive 
>>>> designs that use exclusively tuple-based patterns and no parameter packs. 
>>>> I think Rust once considered a similar approach, although their proposal 
>>>> ended up introducing a parameter-pack like construct for use with fn 
>>>> application: https://github.com/rust-lang/rfcs/issues/376
>>> 
>>> As far as I can tell, the way you are approaching `apply` would not allow 
>>> the default arguments of the function passed as `function` to be used when 
>>> calling `apply`.  Arguments would have to be provided for all parameters 
>>> when the function is invoked through apply.
>> 
>> Yes. There are a lot of issues right now with the idea of using a value pack 
>> or a tuple to call a function, and most of them apply to the tuple splat 
>> discussion that took place a few months ago. Namely, the idea of a tuple or 
>> 'vector' of values does not map cleanly to Swift's function parameter 
>> conventions. You have inout params, params with default values, argument 
>> labels, and other stuff that tuples can't represent cleanly or at all.
>> 
>>> 
>>> I know that this difficulty is not directly related to variadic generics, 
>>> but it does demonstrate a limitation of this approach to forwarding.
>>> 
>>> I have already run into a use case where I would like to accept a function 
>>> and a pack of arguments, store the arguments, be able to compare them for 
>>> equality, and later invoke the function with them.  However, in order for 
>>> this approach to make sense in my use case it would be essential that the 
>>> user *not* need to explicitly provide arguments for parameters with 
>>> defaults.
>>> 
>>> I bring this up in hopes that we might try to explore designs that would 
>>> support this use case, and at least give it some consideration.  I’m trying 
>>> to think of ways to make this work but haven’t come up with anything 
>>> obvious yet.
>> 
>> I do want to explore designs in this space, and I think we will need to 
>> figure it out at some point.
>> 
>> If a good solution cannot present itself in the time frame, I'd be willing 
>> to punt for the purposes of this proposal.
> 
> I am ok with that as long as we can see a path forward to a more robust 
> forwarding solution that can sit beside the variadic generics feature.  It 
> would be unfortunate if we move ahead and later find out that we did 
> something that makes more robust forwarding more difficult to design for one 
> reason or another.
> 
>> My idea of a (sad, awful) fallback solution is to prohibit apply on 
>> functions with inout params, require an argument for every argument in the 
>> formal parameter list, and allow a fully qualified function reference to be 
>> called without re-specifying the argument labels:
>> 
>> struct Foo {
>>   func myFunc(x: Int, y: Int) { }
>>   func myFunc(x: Int, z: Int) { }
>> }
>> 
>> let x = Foo()
>> let theFunc = x.myFunc(_:y:)
>> // Cannot do this now
>> x.myFunc(_:y:)(1, 2)
>> // Have to do this:
>> x.myFunc(_:y:)(1, y: 2)  // but 'y' is redundant on right; this was 
>> discussed during the tuple splat thread
> 
> I haven't tried this.  It actually surprised me.  I thought the unlabeled 
> tuple would implicitly work where a labeled tuple with the same sequence of 
> member types was required.
> 
>> 
>> // In the future...
>> x.someFunc(_:y:z...:)(1, 2, myPack...)
>> 
>>> 
>>> -Matthew
>> 
>> [*] On a tangential topic, how is Swift going to handle generics across 
>> module boundaries in the future? People are complaining that their library 
>> generics code is too slow because specialization is impossible, and 
>> specialization only happens on stdlib generic types because of some hacks. 
>> https://github.com/lorentey/BTree#generics notes that @_specialize might be 
>> exposed as an attribute for library author use in the future. It might be 
>> the case that every variadic generic type might need to be @_specialize by 
>> default, because I can't imagine a variadic equivalent to the 
>> dynamic-dispatch solution currently used to implement regular generics 
>> without specialization.
> 
> Agree that cross module specialization (and WPO generally) is very important. 
> When modules have a nontrivial performance cost (inability to specialize 
> generics) their use is discouraged to some degree.
> 
>> 
>>>> 
>>>> Feedback would be greatly appreciated. Again, be unsparing.
>>>> 
>>>> Best,
>>>> Austin
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected]
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to