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). But I would like to address a few final points.
(inline) On Fri, May 27, 2016 at 12:06 PM, Matthew Johnson <[email protected]> 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. > > > 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. > 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 <[email protected]> > wrote: > > > > Sent from my iPad > > On May 27, 2016, at 11:18 AM, Austin Zheng <[email protected]> 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 < > [email protected]> wrote: > > > Am 27.05.2016 um 16:54 schrieb Matthew Johnson <[email protected]>: > > > On May 27, 2016, at 8:18 AM, Thorsten Seitz via swift-evolution < > [email protected]> 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 <[email protected]>: > > 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 > <[email protected] <mailto:[email protected] > <[email protected]>>>: > > 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 > >), > 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 > ([email protected] <mailto:[email protected] > <[email protected]>>) 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 < > [email protected] <mailto:[email protected] > <[email protected]>>> wrote: > >> > >> > >>> on Thu May 26 2016, Adrian Zubarev <[email protected] < > mailto:[email protected] <[email protected]>>> 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 > >> [email protected] <mailto:[email protected] > <[email protected]>> > >> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > > swift-evolution mailing list > > [email protected] <mailto:[email protected] > <[email protected]>> > > https://lists.swift.org/mailman/listinfo/swift-evolution > > > _______________________________________________ > swift-evolution mailing list > [email protected] <mailto:[email protected] > <[email protected]>> > https://lists.swift.org/mailman/listinfo/swift-evolution > > > _______________________________________________ > swift-evolution mailing list > [email protected] <mailto:[email protected] > <[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 > > > _______________________________________________ > 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
