> Am 27.05.2016 um 21:41 schrieb Matthew Johnson <matt...@anandabits.com>: > > >> On May 27, 2016, at 2:26 PM, Austin Zheng <austinzh...@gmail.com >> <mailto:austinzh...@gmail.com>> wrote: >> >> Thanks for all your thoughtful replies. >> >> I'm not really invested in arguing this much further, as it's mainly a >> stylistic thing that I could live with and also probably a hopeless battle >> (given how everyone else disagrees). > > I’ve been in the same place with some of the other stylistic battles. :-) > >> But I would like to address a few final points. >> >> (inline) >> >> On Fri, May 27, 2016 at 12:06 PM, Matthew Johnson <matt...@anandabits.com >> <mailto:matt...@anandabits.com>> wrote: >> >> >> Turning it around, we don’t have to put parentheses around function types >> and nobody complains about it being problematic even for higher-order >> functions with several steps before the final result. >> >> Function types have a very regular syntax, especially now that 0066 was >> accepted (which, I admit, was very controversal itself): >> >> ( <one or more types> ) -> (tuple) >> or >> ( <one or more types> ) -> SingleTypeWithNoSpaces >> or >> ( <one or more types> ) -> GenericType<All, Spaces, Are, Inside, The, >> Brackets> >> >> A function type is very easy to visually parse: combine the argument parens, >> arrow thing, and the single type that it returns. That being said, complex >> function types are probably the most difficult types to read in a function >> declaration today, even with this regular structure. >> >> The proposed syntax, which allows arbitrary whitespace outside the context >> of a delimiter, would require the user to scan the string comprising the >> existential type expression for a very common sigil in order to locate the >> endpoint: '=' for variable declarations (which admittedly isn't that bad) or >> ',' for functions (which is a lot worse). Not to mention the point Joe Groff >> brought up about a generic function with a generic where clause returning an >> existential and having everything devolve into a undifferentiated soup of >> identifiers. >> >> >> Does anyone know if users of Ceylon or other languages with the >> unparenthesized syntax find it problematic? How would they feel about being >> required to use parentheses? >> >>> >>> We're trying to establish a syntax that will hopefully be used for things >>> significantly more complicated than tuple definitions, which are just a >>> list of types. I think readability is a major concern. Typealiases should >>> be supported, but they shouldn't be required to make the feature useable. >> >> I agree, but I don’t think they would be required to make the feature >> useable just because parentheses are not required. If a developer or team >> thinks they are required for clarity / readability, etc they are free to use >> them. This is a style issue that should be addressed by a linter, not the >> formal syntax of the language. >> >> It is a style issue, but so is (Int) -> T versus Int -> T and a lot of other >> language details like trailing commas in argument lists, of which the core >> team seems to feel pretty strongly about. > > Fair enough! :-) > >> >> >>> >>> Finally, wouldn't we need some delimiter for nested existential definitions >>> anyways? Now you have the confusing situation where the outside definition >>> has no delimiters, but the inside ones do: >>> >>> // Why does the inner existential look fundamentally different than the >>> outer one? >>> // Not to mention, visually parsing the boundaries of this type when you >>> look at it in a function signature >>> let x : Protocol1, Protocol2, (Protocol 3 where .Foo == Int) where >>> Protocol2.Bar : Baz >> >> Nested existentials are supported not because it would ever be a good idea >> to actually write them. They are supported to allow composition of >> existentials: >> >> >> Perhaps then we should only allow existentials to be nested if a typealias >> is used. Swift is, after all, an opinionated language. If a feature is in >> the language, it should either be usable directly in an ergonomic way, or it >> shouldn't be there at all. Having a self-admittedly "bad" way to nest >> literal existential expressions just for consistency when typealiases are >> the preferred use case is very unlike Swift. > > I think self-admittedly “bad” is a bit of a stretch. I do *think* the > conventional style would be to match the rest of Swift. But I’m not > *certain* of that. I could see the style Thorsten posted being conventional > and useful in some cases: > > let x : Protocol1 & (Protocol2 where .Bar : Baz) & (Protocol 3 where .Foo == > Int) > > I think direct `&` syntax will be most useful when combining two (or maybe > three) protocols with no associated types: `Protocol1 & Protocol2` (whether > or not we require parens). > > Generally I hope we will use type aliases for existentials that are this > complex just as we usually bind names to parts of expressions rather than > writing large one-liners. > > One issue I’m not sure we have addressed is the case of an existential for a > single protocol with an associated type constraint `Protocol where .Foo = > Int`. Before we settle on a syntax we should be sure that this doesn’t > introduce any ambiguity.
Austin raised the point (or reminded of Joe’s raising the point) of possible problems when returning constrained existentials from generic functions: func foo<P, Q>(p: P, q: Q) -> any<Collection where .Element == P> where P: Equatable { … } would require parentheses when using `&` instead of any<> func foo<P, Q>(p: P, q: Q) -> (Collection where .Element == P) where P: Equatable { … } This would even be the case if there was no constraint on P: func foo<P, Q>(p: P, q: Q) -> (Collection where .Element == P) { … } An alternative would be to use `with` for existentials instead of `where`: func foo<P, Q>(p: P, q: Q) -> Collection with .Element == P where P: Equatable { … } But even then this would be more readable either with parentheses (now just as a matter of style) or a line break: func foo<P, Q>(p: P, q: Q) -> Collection with .Element == P where P: Equatable { … } -Thorsten > > -Matthew > >> >> typealias P3Int = Protocol 3 where .Foo == Int >> let x : Protocol1, Protocol2, P3Int where Protocol2.Bar : Baz >> >> If you are writing the entire type in a single location I expect the >> conventional style to be like this: >> >> let x : Protocol1, Protocol2, Protocol 3 where Protocol2.Bar : Baz, >> Protocol3.Foo == Int >> >> With all associated types constraints in a single `where` clause as we other >> places they are written in Swift. >> >> Maybe I am wrong about that and a different conventional style would emerge >> (for example, where clauses clustered with the related protocol). >> >> But *requiring* parentheses is really orthogonal to the style issue of where >> and when it is considered *advisable* to use them. >> >> -Matthew >> >>> >>> I hope that explains my reasoning. >>> >>> Best, >>> Austin >>> >>> >>>> On May 27, 2016, at 9:28 AM, Matthew Johnson <matt...@anandabits.com >>>> <mailto:matt...@anandabits.com>> wrote: >>>> >>>> >>>> >>>> Sent from my iPad >>>> >>>> On May 27, 2016, at 11:18 AM, Austin Zheng <austinzh...@gmail.com >>>> <mailto:austinzh...@gmail.com>> wrote: >>>> >>>>> Here's a strawman idea. >>>>> >>>>> What if we go with '&' and 'where', but we enclose the whole thing in >>>>> parentheses? >>>>> >>>>> (class & Protocol1 & Protocol2 where .Foo == Int, .Bar : Baz) >>>>> >>>>> There are a couple of reasons I propose this syntax: >>>>> >>>>> - It makes it very clear where the definition of the type begins and >>>>> ends. I understand people really despise angle brackets, but I really >>>>> want some way to visually delineate the boundaries of the type. Plus, I >>>>> imagine it makes syntax a little easier to parse and preemptively forbids >>>>> some ambiguities. >>>>> >>>>> - It's a structural, not nominal, type, like a tuple, so it uses parens >>>>> as well. This reserves "<" and ">" for generic types. >>>>> >>>>> - The '&' is easily understood - "Protocol1" *and* "Protocol2". It's also >>>>> a signal that order doesn't matter - just like how order matters with >>>>> things that use commas, like argument lists, tuples, and array members, >>>>> order doesn't generally matter with bitwise or logical 'and' operators. >>>>> >>>>> - If we ever decide to have union types, we have a very elegant third >>>>> form of nominal type syntax that naturally falls out: (MyClass1 | >>>>> MyClass2 | MyClass3). >>>>> >>>>> Thoughts? >>>> >>>> Generally in favor. But I would not require the parentheses. I believe >>>> they would be allowed optionally automatically, just as (Int) is the same >>>> as Int (because single element tuples don't exist and the underlying type >>>> is used directly instead). It seems better to leave parentheses up to a >>>> matter of style. >>>> >>>> >>>>> >>>>> Austin >>>>> >>>>> >>>>>> On May 27, 2016, at 9:07 AM, Thorsten Seitz via swift-evolution >>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>>> >>>>>> >>>>>>> Am 27.05.2016 um 16:54 schrieb Matthew Johnson <matt...@anandabits.com >>>>>>> <mailto:matt...@anandabits.com>>: >>>>>>> >>>>>>>> >>>>>>>> On May 27, 2016, at 8:18 AM, Thorsten Seitz via swift-evolution >>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>>>>> >>>>>>>> Personally I think `&` is more lightweight (and it is established in >>>>>>>> other languages like Ceylon and Typescript) and `where` is more >>>>>>>> expressive (and established in Swift for introducing constraints), so >>>>>>>> I would stay with these. >>>>>>> >>>>>>> I agree. If we can make `&` with `where` work syntactically it would >>>>>>> be nice to go in this lighter weight direction. If we decide to do >>>>>>> that the question then becomes what to do with `protocol`. Would it be >>>>>>> feasible to replace it with `&` in Swift 3 if we decide on that >>>>>>> direction? >>>>>> >>>>>> Yep. `protocol` should be replaced with `&` in that case. >>>>>> >>>>>> -Thorsten >>>>>> >>>>>> >>>>>>> >>>>>>>> >>>>>>>> -Thorsten >>>>>>>> >>>>>>>> >>>>>>>>> Am 27.05.2016 um 14:34 schrieb Vladimir.S <sva...@gmail.com >>>>>>>>> <mailto:sva...@gmail.com>>: >>>>>>>>> >>>>>>>>> Btw, in case we have `where` keyword in syntax related to >>>>>>>>> types/protocols (when defining constrains. and not some symbol like >>>>>>>>> '>>'.. don't know, for example), why we can't have 'and' keyword also >>>>>>>>> when discuss the syntax of type/protocol conjunction? >>>>>>>>> I.e. >>>>>>>>> >>>>>>>>> let x: P and Q >>>>>>>>> let x: P and Q where P.T == Q.T >>>>>>>>> let x: P and Q and R >>>>>>>>> >>>>>>>>> or, for consistency, as I understand it, we should have >>>>>>>>> let x: P & Q >> P.T == Q.T >>>>>>>>> >>>>>>>>> On 27.05.2016 11:55, Thorsten Seitz via swift-evolution wrote: >>>>>>>>>> We could just write >>>>>>>>>> >>>>>>>>>> let x: P & Q >>>>>>>>>> instead of >>>>>>>>>> let x: Any<P, Q> >>>>>>>>>> >>>>>>>>>> let x: Collection where .Element: P >>>>>>>>>> instead of >>>>>>>>>> let x: Any<Collection where .Element: P> >>>>>>>>>> >>>>>>>>>> let x: P & Q where P.T == Q.T >>>>>>>>>> instead of >>>>>>>>>> let x: Any<P, Q where P.T == Q.T> >>>>>>>>>> >>>>>>>>>> let x: P & Q & R >>>>>>>>>> instead of >>>>>>>>>> let x: Any<P, Q, R> >>>>>>>>>> >>>>>>>>>> let x: Collection >>>>>>>>>> instead of >>>>>>>>>> let x: Any<Collection> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> This would avoid the confusion of Any<T1, T2> being something >>>>>>>>>> completely >>>>>>>>>> different than a generic type (i.e. order of T1, T2 does not matter >>>>>>>>>> whereas >>>>>>>>>> for generic types it is essential). >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -Thorsten >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> Am 26.05.2016 um 20:11 schrieb Adrian Zubarev via swift-evolution >>>>>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>> <mailto:swift-evolution@swift.org >>>>>>>>>>> <mailto:swift-evolution@swift.org>>>: >>>>>>>>>>> >>>>>>>>>>> Something like |type<…>| was considered at the very start of the >>>>>>>>>>> whole >>>>>>>>>>> discussion (in this thread >>>>>>>>>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016523.html >>>>>>>>>>> >>>>>>>>>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016523.html>>), >>>>>>>>>>> but it does not solve the meaning of an existential type and also >>>>>>>>>>> might >>>>>>>>>>> lead to even more confusion. >>>>>>>>>>> >>>>>>>>>>> From my perspective I wouldn’t use parentheses here because it >>>>>>>>>>> looks more >>>>>>>>>>> like an init without any label |Type.init(…)| or |Type(…)|. I could >>>>>>>>>>> live >>>>>>>>>>> with |Any[…]| but this doesn’t look shiny and Swifty to me. Thats >>>>>>>>>>> only my >>>>>>>>>>> personal view. ;) >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Adrian Zubarev >>>>>>>>>>> Sent with Airmail >>>>>>>>>>> >>>>>>>>>>> Am 26. Mai 2016 bei 19:48:04, Vladimir.S via swift-evolution >>>>>>>>>>> (swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>> <mailto:swift-evolution@swift.org >>>>>>>>>>> <mailto:swift-evolution@swift.org>>) schrieb: >>>>>>>>>>> >>>>>>>>>>>> Don't think {} is better here, as they also have "established >>>>>>>>>>>> meaning in >>>>>>>>>>>> Swift today". >>>>>>>>>>>> >>>>>>>>>>>> How about just Type(P1 & P2 | P3) - as IMO we can think of such >>>>>>>>>>>> construction as "creation" of new type and `P1 & P2 | P3` could be >>>>>>>>>>>> treated >>>>>>>>>>>> as parameters to initializer. >>>>>>>>>>>> >>>>>>>>>>>> func f(t: Type(P1 & P2 | P3)) {..} >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On 26.05.2016 20:32, L. Mihalkovic via swift-evolution wrote: >>>>>>>>>>>> > How about something like Type{P1 & P2 | P3} the point being that >>>>>>>>>>>> > "<...>" has an established meaning in Swift today which is not >>>>>>>>>>>> > what is expressed in the "<P1,P2,P3>" contained inside Any<P1, >>>>>>>>>>>> > P2,P3>. >>>>>>>>>>>> > >>>>>>>>>>>> >> On May 26, 2016, at 7:11 PM, Dave Abrahams via swift-evolution >>>>>>>>>>>> >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>>> >> <mailto:swift-evolution@swift.org >>>>>>>>>>>> >> <mailto:swift-evolution@swift.org>>> wrote: >>>>>>>>>>>> >> >>>>>>>>>>>> >> >>>>>>>>>>>> >>> on Thu May 26 2016, Adrian Zubarev <swift-evolution@swift.org >>>>>>>>>>>> >>> <mailto:swift-evolution@swift.org> >>>>>>>>>>>> >>> <mailto:swift-evolution@swift.org >>>>>>>>>>>> >>> <mailto:swift-evolution@swift.org>>> wrote: >>>>>>>>>>>> >>> >>>>>>>>>>>> >>> There is great feedback going on here. I'd like to consider a >>>>>>>>>>>> >>> few things here: >>>>>>>>>>>> >>> >>>>>>>>>>>> >>> * What if we name the whole thing `Existential<>` to sort out >>>>>>>>>>>> >>> all >>>>>>>>>>>> >>> confusion? >>>>>>>>>>>> >> >>>>>>>>>>>> >> Some of us believe that “existential” is way too theoretical a >>>>>>>>>>>> >> word to >>>>>>>>>>>> >> force into the official lexicon of Swift. I think “Any<...>” is >>>>>>>>>>>> >> much >>>>>>>>>>>> >> more conceptually accessible. >>>>>>>>>>>> >> >>>>>>>>>>>> >>> >>>>>>>>>>>> >>> This would allow `typealias Any = Existential<>`. * Should >>>>>>>>>>>> >>> `protocol A: Any<class>` replace `protocol A: class`? Or at >>>>>>>>>>>> >>> least >>>>>>>>>>>> >>> deprecate it. * Do we need `typealias AnyClass = Any<class>` >>>>>>>>>>>> >>> or do we >>>>>>>>>>>> >>> want to use any class requirement existential directly? If >>>>>>>>>>>> >>> second, we >>>>>>>>>>>> >>> will need to allow direct existential usage on protocols >>>>>>>>>>>> >>> (right now we >>>>>>>>>>>> >>> only can use typealiases as a worksround). >>>>>>>>>>>> >> >>>>>>>>>>>> >> -- >>>>>>>>>>>> >> Dave >>>>>>>>>>>> >> >>>>>>>>>>>> >> _______________________________________________ >>>>>>>>>>>> >> swift-evolution mailing list >>>>>>>>>>>> >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>>> >> <mailto:swift-evolution@swift.org >>>>>>>>>>>> >> <mailto:swift-evolution@swift.org>> >>>>>>>>>>>> >> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>>>>>> > _______________________________________________ >>>>>>>>>>>> > swift-evolution mailing list >>>>>>>>>>>> > swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>>> > <mailto:swift-evolution@swift.org >>>>>>>>>>>> > <mailto:swift-evolution@swift.org>> >>>>>>>>>>>> > https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>>> > <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>>>>>> > >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>>> <mailto:swift-evolution@swift.org >>>>>>>>>>>> <mailto:swift-evolution@swift.org>> >>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> swift-evolution mailing list >>>>>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>> <mailto:swift-evolution@swift.org >>>>>>>>>>> <mailto:swift-evolution@swift.org>> >>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> swift-evolution mailing list >>>>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>>> _______________________________________________ >>>>>>>> swift-evolution mailing list >>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>> _______________________________________________ >>>>>> swift-evolution mailing list >>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >> >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution