[swift-evolution] [pitch] Eliminate the "T1 -> T2" syntax, require "(T1) -> T2"

Howard Lovatt howard.lovatt at gmail.com
Fri Apr 15 21:41:13 CDT 2016


Doesn't really seem worth the trouble to me. It is fine as it is. Other
languages like Java and Scala allow this short hand and Swift allows it in
closures. Not that I am that fussed since the brackets are no big deal.

On Saturday, 16 April 2016, John McCall via swift-evolution <
swift-evolution at swift.org> wrote:

> > On Apr 15, 2016, at 2:47 PM, Joe Groff <jgroff at apple.com <javascript:;>>
> wrote:
> >> On Apr 15, 2016, at 11:43 AM, John McCall <rjmccall at apple.com
> <javascript:;>> wrote:
> >>> On Apr 15, 2016, at 10:41 AM, Joe Groff <jgroff at apple.com
> <javascript:;>> wrote:
> >>>> On Apr 15, 2016, at 8:29 AM, John McCall via swift-evolution <
> swift-evolution at swift.org <javascript:;>> wrote:
> >>>>
> >>>>> On Apr 14, 2016, at 10:50 PM, Chris Lattner <clattner at apple.com
> <javascript:;>> wrote:
> >>>>> On Apr 14, 2016, at 10:40 PM, John McCall <rjmccall at apple.com
> <javascript:;>> wrote:
> >>>>>>>> To me, the unparenthesized style suggests that the input and
> output are peers, which feels more natural for the sort of value-to-value
> transform/predicate where this most commonly occurs.  Parenthesizing the
> input feels fussier, which contributes to a sense that the argument is just
> one component to producing the result.
> >>>>>>>> The parentheses are grammatically unnecessary in most cases (by
> frequency of use in higher-use programming, not by feature count).
> >>>>>>>
> >>>>>>> I agree with your point that many simple higher order programming
> examples (e.g. map, filter, etc) take a single argument. That said, I don’t
> agree that this means that we should syntactically privilege this special
> case.
> >>>>>>
> >>>>>> "Special case" is a loaded phrase.  Why is it a special case as a
> parameter if it isn't a special case as a result?
> >>>>>
> >>>>> Because, as I tried to explain in my original post, parameters *are*
> a special case.  The result type of a function is just a type. The
> parameter list allows things that types do not: default arguments and
> variadics.
> >>>>
> >>>> Default arguments are not allowed in the type grammar.  Nor are
> different internal vs. external labels.
> >>>>
> >>>>> As a concrete example, surely you aren’t arguing that we should
> support:
> >>>>>
> >>>>>   let x : Int… -> Int
> >>>>>
> >>>>> are you?
> >>>>
> >>>> No, but that's because the ... is a reference to the rest of the
> tuple and doesn't read correctly outside of one.
> >>>>
> >>>>>>>> I guess the flip side is that call and declaration syntax both
> require parentheses (unless the only argument is a trailing closure), but
> again, we had strong justifications for that: declarations would always be
> ambiguous without parens, and calls would have serious problems (and the
> style-wars factor would be much larger, especially now with mandatory
> keyword arguments by default).
> >>>>>>>
> >>>>>>> Right, but regardless of *why* we always require parens on Decls
> and ApplyExprs, we really do (and that isn’t going to change). Being
> consistent between func decls and function types is quite important IMO.
> >>>>>>
> >>>>>> So we should require function argument labels in function types?
> >>>>>
> >>>>> Uhm, yes, we already do.  In:
> >>>>>
> >>>>>   let x : (a : Int) -> Float
> >>>>>   let y : (Int) -> Float
> >>>>>   let z : Int -> Float
> >>>>>
> >>>>> x and y have different (but compatible) types. y and z have
> identical types (sugared differently).
> >>>>
> >>>> When I said "function type", I was referring to this production in
> the type grammar, not the type signature component of function
> declarations.  I'm not sure how I could've been clearer on that without
> actually using the names of grammatical productions.
> >>>>
> >>>> My point was that allowing a function type to be written as "(Int) ->
> Float" is already inconsistent with function declarations, because that is
> not legal function declaration syntax; you would have to write "(_ : Int)
> -> Float".
> >>>>
> >>>> The current language composes naturally here, and your proposal feels
> like an odd extra rule.
> >>>
> >>> I feel like the current language no longer represents our reality,
> though (or at least, our current ideal vision for reality). We've pretty
> thoroughly broken the "functions have one argument" model.
> >>
> >> I don't see this syntax as an offshoot of the "functions always have
> one argument" model.  I agree that that model is dead.
> >>
> >> However, I don't think users require its death to be underlined and
> written in bold; it only ever surfaced to them in bugs anyway.  But many
> functions do, nonetheless, have only one argument; and because of another
> change to the model, where argument labels are becoming part of the
> function's name and not its type, that argument can be written as just a
> type.
> >>
> >> So to me, this question is whether we add a weird special-case rule
> that mandates the use of parentheses because they're required in a bunch of
> more complex but less common situations.
> >>
> >>> Changing the type grammar to reflect this seems good to me. I would
> think of it as changing the function type grammar to:
> >>>
> >>>     function-type ::= '(' (type (',' type)*)? ')' '->' type
> >>>
> >>> which, since the argument list can containing 0, 1, or many individual
> arguments, makes the parens more grammatically necessary.
> >>
> >> This is tautological.
> >
> > I don't think it is just a tautology. Without encoding it in the
> grammar, there's an ambiguity between tuples and multiple arguments; () ->
> T could mean either "takes a single () argument" or "takes no arguments".
> We could "obviously" disambiguate in favor of the latter interpretation,
> but then you're introducing special cases in the other direction to keep
> the U -> T syntax working.
>
> This is a fair point, and one which would come up with (Int,Int) -> Float
> as well — maybe the user really does mean to pass a single value that's an
> (Int,Int) pair.  I'm not sure this really works out to being a special case
> at the user level, though, since in either model the user trying to write a
> function that takes a single tuple-typed parameter simply has to introduce
> the extra parens: (()) -> Float or ((Int, Int)) -> Float.  (Assuming that
> the type system preserves that structure in any way, of course.)
>
> John.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <javascript:;>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>


-- 
-- Howard.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160416/473aa00d/attachment.html>


More information about the swift-evolution mailing list