> 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

Reply via email to