[swift-evolution] [Proposal] Variadics as Attribute

Leonardo Pessoa me at lmpessoa.com
Thu Jul 7 16:39:54 CDT 2016

I believe the alternative can be even simpler if you consider the type
of the variadic argument is in fact an array. The different syntax
tell the compiler it can relax on demanding an array for that argument
and allow multiple comma-separated values of the same declared type.
Nothing but the compiler complains if you try and pass an array there,
so the compiler could simply be updated to allow a list of arguments
or an array. Also, the compiler knows the type of the variadic
argument and the argument(s) you're passing so if you have 'Int...' it
should be able to recognise a [Int] as a valid (ans single) value.

One other alternative (or complement) is to use ar simple syntax to
tell the compiler you want to use the values of an array. In Ruby the
equivalent of our "args : String..." is simply "*args" (no types in
Ruby) and I can use the array or pass it as a variadic argument to
another function by passing "*args" instead of simply "args". It may
not be much nice visually but one could be able to use something like
"args..." here (I'm open to other suggestions, of course) just to
explicit/ensure that is what you want to do.

IMHO there is nothing that could be gained here with the change in
syntax (perhaps only a clarification that a variadic argument is an
array of that type for someone new to the language, but that's still
more verbose). Even if we were to change the syntax it would still
require changes on how the compiler perceives the arguments passed to
a function and I think we'd have less effort (and less breaking more
backward compatibility) if we just allow variadic arguments to receive
arrays of its type directly.


On 7 July 2016 at 18:15, Haravikk via swift-evolution
<swift-evolution at swift.org> wrote:
> Posted a new proposal, feedback appreciated:
> https://github.com/Haravikk/swift-evolution/blob/2743411af02e3ac6761fbdd780ede1af4cc34ee7/proposals/0000-variadics-as-attribute.md
> One talking point raised already is the correct location for the attribute
> (parameter or type); I'm undecided personally as there are arguments for
> both, probably not an important detail though (core team can make a decision
> on that I think), since the guidelines on attributes have been debated a few
> times already.
> Also, no matter how much I use it I seem to be the worst at using the Github
> website, so apologies for my many mistakes on that side of things ;)
> Variadics as Attribute
> Proposal: SE-NNNN
> Author: Haravikk
> Status: Awaiting review
> Review manager: TBD
> Introduction
> This proposal is for a redesign of the variadic function parameter syntax as
> an attribute for greater flexibility.
> Motivation
> Currently Swift variadic functions cannot be called with an array of values,
> potentially requiring two declarations like so:
> func someMethod<C:Collection where C.Iterator.Element == Int>(_ values:C) {
> … } // Regular method
> func someMethod(_ values:Int...) { someMethod(values) } // Variadic method
> In some cases this leads to only one being defined, forcing developers to
> use that particular style. When this is the variadic option this means the
> method is restricted in how it can be used, and parameters constructed.
> Proposed solution
> This proposal is to replace the current form of variadic declaration syntax
> (trailing elipsis) with a new attribute @variadicthat enables any suitable
> iterable parameter to be called in variadic form if desired.
> Detailed design
> Quite simply, instead of a trailing elipsis, a variadic parameter will
> instead be defined via a new @variadic attribute which can be placed upon
> any function parameter with a type conforming to ArrayLiteralConvertible, or
> which is a generic constraint against IteratorProtocol, Sequence or
> Collection such that a default (such as Array) can be used to fulfil the
> variadic call. Otherwise variadic parameters can be specified with the same
> restrictions they have now (must not be ambiguous).
> For example, consider the following variadic function:
> func someMethod(_ values:Int...) { … }
> Under this proposal the above can be rewritten as one of the following:
> func someMethod(@variadic _ values:[Int]) { … } // Basic Array solution
> func someMethod(@variadic _ values:Foo) { … }   // Foo is a custom
> ArrayLiteralConvertible type
> func someMethod<I:IteratorProtocol where I.Element == Int>(@variadic _
> values:I) { … } // Flexible, single-pass, generic solution
> func someMethod<S:Sequence where S.Iterator.Element == Int>(@variadic _
> values:S) { … } // Flexible, (probably) multi-pass, generic solution
> func someMethod<C:Collection where C.Iterator.Element == Int>(@variadic _
> values:C) { … } // Flexible, definitely multi-pass, indexed, generic
> solution
> In this case the Iterator variation is preferred for greatest flexibility,
> but it will depend upon the actual requirements of the method. Any of these
> can be called as follows:
> someMethod([1, 2, 3, 4, 5, 6])  // normal array-literal call for any of the
> above
> someMethod(1, 2, 3, 4, 5, 6)    // variadic call, synonymous with
> array-literal call
> someMethod(foo)                 // foo is an existing Array, Foo, Iterator,
> Sequence or Collection variable as appropriate
> This altered declaration syntax has a number of advantages over existing
> variadics:
> No requirement for a custom syntax (see alternatives however)
> A single declaration can handle variadic and collection/sequence/iterator
> invocation (no need for some other workaround such as reflection).
> Greater flexibility over the actual type of the variadic
> collection/sequence/iterator, not restricted to Array or array-like.
> Developers are free to choose the syntax used at the call-site based upon
> preference (or pass a variable instead).
> Declaration is more discoverable (option-click the @variadic attribute to
> view documenation).
> Impact on existing code
> This proposal as given would remove the existing variadic syntax (trailing
> elipsis), but a fix-it should enable easy conversion between the following:
> func someMethod(_ values:Int...) { … } // Old style
> func someMethod(@variadic _ values:[Int]) { … } // New style
> However there is an alternative to consider below that will affect this.
> Alternatives considered
> One alternative is to simply have the existing variadic syntax produce a
> method taking an array of the same type, that is implicitly capable of being
> used in variadic style (but also used directly with Array values). However
> this has less flexibility than the above, which permits non-Array types. A
> compromise could be to allow the existing style to remain as a shorthand,
> though this may discourage consideration of the most appropriate type (in
> general developers should be encouraged to accept generic types for greatest
> utility wherever possible, but if trailing elipsis is easy we may just end
> up with Array being used most often).
> The other main alternative considered was removing variadics completely;
> while this is actually the preference of some (myself included), it seems a
> lot developers do not wish this. This proposal is intended as a compromise
> that coallesces variadics with regular functions, without eliminating the
> possibility to use either style at the call site as developers prefer.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

More information about the swift-evolution mailing list