[swift-evolution] Idea: Let Generic Parameters Have Labels & Default Values

davesweeris at mac.com davesweeris at mac.com
Wed Jan 27 01:30:31 CST 2016


This is the 2nd time someone has pointed out that this, at least AFAICT, provides related functionality to parts of other proposals. It seems counterproductive to have multiple proposals out there with conflicting syntax for the same thing, especially when the different syntaxes could potentially have different corner-cases, which could be important to other parts of the proposal. Is there a “standard” way to make sure this isn’t stepping on anyone’s toes?

- Dave Sweeris

> On Jan 25, 2016, at 15:03, Maximilian Hünenberger <m.huenenberger at me.com> wrote:
> 
> In another thread:
> 
> [swift-evolution] Partially Constrained Protocols [Was:	[Proposal] Separate protocols and interfaces]
> 
> 
> This problem (and many others) could be solved with:
> 
>         let foo = Foo<where Self.U == Whatever>(bar)
> 
> Where `T` is inferred to be of type `Int`.
> 
> 
> While this example is pretty verbose this kind of syntax can be used to use protocols with associated types as variables and generic covariant types.
> 
> 
> +1 for having label like behavior but they shouldn't be explicit since there could be confusion whether you declare a generic type or only a label. Therefore implicit typealiases (in this case `U` and `T`) should be used in conjunction with the approach above.
> 
> -1/+1 for default generic types because I imagine them to be useful in some (special) cases but I couldn't think of any useful real problem. So the additional syntax could not be worth its benefit.
> 
> 
> Best regards
> - Maximilian
> 
> Am 25.01.2016 um 20:44 schrieb Dave via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
> 
>> I’m not saying default values should be required, just that they be allowed if it makes sense. Plus, the way Array is defined, its generic parameter can always be inferred. In your example, `a` would be an array of IntergerLiteralType (which is currently typealiased to Int). However, it’s perfectly legal to define a struct for which the compiler can’t always infer all the generic parameters
>> struct Foo <T, U> {
>>     var value: T
>>     var opt2ndValue: U?
>>     init(_ value: T, opt2ndValue: U? = nil) {
>>         self.value = value
>>         self.opt2ndValue = opt2ndValue
>>     }
>> }
>> In which case, the following code won’t compile:
>> let foo = Foo(bar)
>> because U can’t be inferred. The current workaround:
>> let foo = Foo<Int, Whatever>(bar)
>> requires you to specify all the types, which means that bar cannot be an inferred type, because this isn’t valid:
>> let foo = Foo<bar.dynamicType, Whatever>(bar)
>> 
>> Default values for generic parameters let you maintain type inference, if it would make sense in your case. If it doesn’t, then don’t provide one.
>> 
>> - Dave Sweeris
>> 
>>> On Jan 25, 2016, at 01:00, Howard Lovatt <howard.lovatt at gmail.com <mailto:howard.lovatt at gmail.com>> wrote:
>>> 
>>> +1 for labels, I think generics are special arguments to `inits` and therefore labels make sense to me.
>>> 
>>> -1 for default values, the value is inferred if not specifically specified. What would:
>>> 
>>>     let a = [1]
>>> 
>>> be? An `Int` array or an array of whatever the default generic type for an array is?
>>> 
>>> Sent from my iPad
>>> 
>>> On 24 Jan 2016, at 7:38 AM, David Sweeris via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>>> The title seems fairly self-explanatory. Does anyone else think this could be useful?
>>>> struct True : BooleanType {…} // Just part of the example… not in the proposal (although I do like it)
>>>> struct False : BooleanType {…}  // Same
>>>> // This is where the actual idea starts
>>>> struct BigInt <BaseType: T = Int, CanEqualZero: U = Yes where T: IntegerArithmeticType, U: BooleanType> {…}
>>>> 
>>>> The first parameter label could be skipped (or not), depending on whatever the rules for functions parameter labels ends up being (either way, they should be the same IMHO). Then variables could be declared like this:
>>>> let foo =   BigInt()	    // BigInt<Int, No>()
>>>> let bar =   BigInt<Int32>() // For when your data will be processed on a 32-bit platform or something
>>>> let divisor = BigInt<CanEqualZero: False>()
>>>> 
>>>> (The obvious follow-up suggestion is to then allow a generic type’s definition to change based on the results of logical operations performed purely on the types that are passed in, but I think that’s getting into “macro system” territory, and should probably be its own thing.)
>>>> 
>>>> Anyway, thoughts?
>>>> 
>>>> - Dave Sweeris
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160126/b3e4d322/attachment.html>


More information about the swift-evolution mailing list