More thoughts on protocols used more systematically to replace compiler magic.

Begin forwarded message:

> From: L Mihalkovic <laurent.mihalko...@gmail.com>
> Date: June 8, 2016 at 8:07:02 AM GMT+2
> To: Thorsten Seitz <tseit...@icloud.com>
> Cc: Michael Peternell <michael.petern...@gmx.at>, swift-evolution 
> <swift-evolut...@swift.org>, Dave Abrahams <dabrah...@apple.com>, Douglas 
> Gregor <dgre...@apple.com>, Joe Groff <jgr...@apple.com>, Chris Lattner 
> <clatt...@apple.com>
> Subject: Re: [swift-evolution] [Draft] Change @noreturn to unconstructible 
> return type
> 
> 
>>> On Jun 8, 2016, at 7:49 AM, L Mihalkovic <laurent.mihalko...@gmail.com> 
>>> wrote:
>>> 
>>> 
>>> On Jun 8, 2016, at 6:57 AM, Thorsten Seitz <tseit...@icloud.com> wrote:
>>> 
>>> I strongly disagree. Type systems are not some esoteric academic thing only 
>>> working for Haskell or functional languages. Just have a look at the type 
>>> systems of other languages like Ceylon, Rust or TypeScript.
>>> 
>>> I hope that Swift will someday have variance annotations for generic 
>>> parameters and associated types so that we may express sound subtyping 
>>> rules between generic types. A real bottom type will fit in there just 
>>> nicely.
>>> 
>>> +1 for a real bottom type
>>> +1 for calling it Never
>> 
>> +1 on all accounts (it is not the first time I find myself in agreement with 
>> many of the choices you support, and more interestingly, with the rational 
>> you use to support them: usually a mix between references to other examples 
>> and pragmatism).
>> 
>> here is another twist on Never… see further down...
>> 
>> 
>>> 
>>> -Thorsten 
>>> 
>>> 
>>>>> Am 07.06.2016 um 22:43 schrieb Michael Peternell via swift-evolution 
>>>>> <swift-evolut...@swift.org>:
>>>>> 
>>>>> 
>>>>> Am 07.06.2016 um 22:14 schrieb L Mihalkovic via swift-evolution 
>>>>> <swift-evolut...@swift.org>:
>>>>> 
>>>>> 
>>>>>>> On Jun 7, 2016, at 9:49 PM, Michael Peternell via swift-evolution 
>>>>>>> <swift-evolut...@swift.org> wrote:
>>>>>>> 
>>>>>>> 
>>>>>>>>> Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution 
>>>>>>>>> <swift-evolut...@swift.org>:
>>>>>>>>> 
>>>>>>>>> On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution 
>>>>>>>>> <swift-evolut...@swift.org> wrote:
>>>>>>>>> 
>>>>>>>>> I disagree. We are discussing how to annotate a function in some way 
>>>>>>>>> so that the compiler knows that the code following it will never be 
>>>>>>>>> executed *and* so a human who reads the declaration knows that it 
>>>>>>>>> does not return. “Never" is a poor choice for that. Never what? Never 
>>>>>>>>> return? Never use this function? Never say never again?
>>>>>>>> 
>>>>>>>> "Never return". That's why it's in the return type slot, right after 
>>>>>>>> the `->`. If you read it out loud, you'll read "returns Never", which 
>>>>>>>> is exactly correct.
>>>>>>>> 
>>>>>>>> NoReturn, on the other hand, does *not* read well in that slot: 
>>>>>>>> "returns NoReturn". Huh? I mean, I suppose you won't misunderstand it, 
>>>>>>>> but it makes no sense whatsoever *as a type name*.
>>>>>>> 
>>>>>>> But it’s *not* a type. You’ll never have an instance of it. Since it’s 
>>>>>>> not a type name, it doesn’t make sense that it needs to look like one. 
>>>>>>> What it is doing is telling you something about the behavior of the 
>>>>>>> function itself, not its return value. Its return value, if there were 
>>>>>>> one, is irrelevant, since the function, by its very nature, will never 
>>>>>>> even get to the point where it would return it. Either it’s going to 
>>>>>>> kill the app via a fatalError or something, or we have something like 
>>>>>>> dispatch_main() which will keep executing until the program stops, and 
>>>>>>> one way or another, it won’t return.
>>>>>>> 
>>>>>>> For that reason, frankly, I don’t understand why we want to change this 
>>>>>>> from being an attribute, which seems to me the more natural and logical 
>>>>>>> choice to describe this behavior. If we *do* have to change it, though, 
>>>>>>> NoReturn conveys the most clearly to the reader what it does.
>>>>>> 
>>>>>> +1 for @noreturn
>>>>>> We don't have to change it.
>>>>>> We have to keep it.
>>>>> 
>>>>> 
>>>>> this is so unfortunate… IMHO the proposal is the right move because it 
>>>>> goes into the direction of unifying things in the language. the problem 
>>>>> is that it is difficult to see it without looking at the language as a 
>>>>> whole. then we realize that this can be connected to the change of 
>>>>> dynamicType to a function or to the fact that .Type and .Self might also 
>>>>> warrant a revisiting.
>>>> 
>>>> from a practical point of view, a @noreturn function is just so much 
>>>> different than any other function. this shouldn't be "unified". we can 
>>>> discuss if bottom types and normal types can be unified from a 
>>>> theoretical/academical point of view. but in the real world, a @noreturn 
>>>> function does not return at all, whereas most other function does return 
>>>> execution to its caller. To honor this view, a function that returns 
>>>> `Void` is meant to return, it just doesn't return any particular value. 
>>>> But `Void` should be the type with no values, not the type with exactly 
>>>> one value, so a function that returns `Void` shouldn't be able to return, 
>>>> because there can be no `Void` value. `Void` is an unconstructable type, 
>>>> and yet it is different from `@noreturn`. That would be a unification ;) . 
>>>> The whole concept of return-values is so much different in imperative 
>>>> programming than it is in Haskell and with "denotational semantics". 
>>>> Therefore we have 1) functions that return a value, e.g. `Int`, 2) 
>>>> functions that return no value (`Void`), and 3) functions that doesn't 
>>>> return at all (`@noreturn`) => I would like to keep it that way.
>>>> 
>> 
>> Consider for a moment that the bottom type is a technical aspect of the 
>> runtime., the thing that the compiler needs so avoid some internal magic 
>> while steering towards expressing more things that can be expressed with 
>> protocols, using protocols. So that would give the compiler what it needs to 
>> have more internal symmetry. But then nothing says that our needs are the 
>> same as the compiler’s, particularly when it comes to expressivity. So that 
>> leaves us with the possibility of having a bottom type, and having something 
>> based on it that can present a more user friendly interface. And while we 
>> are at it, nothing says that the user facing side has to be universal, 
>> fitting all possible use cases. So then that opens up the possibility of 
>> 
>> 1) have a bottom type
>> 2) have use site derived notions (the ones we users will learn) that are 
>> internally linkable to 1), but outside of what we care about
>> 
>> which bring us back to something like the following scenario:
>> 
>> 1)  create a  protocol SwiftBottomType { }   [  the core team might defend 
>> the idea that it should really be BuiltinBottomType, but the argument also 
>> goes that BuiltinXxxxLiteral can be converted to SwiftXxxxLiteral  ]. This 
>> is something only the compiler cares about, but a building block for what we 
>> need. it would be simple to enforce in the compiler that SwiftXXXXX 
>> protocols cannot be the target of any user defined conformances if need be. 
>> In fact, these SwiftXxxxxx protocols could be considered so critical for the 
>> existence of the language/compiler (i.e. ‘below' the stdlib) that might 
>> might not even be represented in the sodlib, but directly manufactured into 
>> the TEXT.__swift3_builtin (don’t quote me on this one versus the meaning of 
>> the __swift2_proto??? can't recall its name at the moment) section of the 
>> libswiftRuntime.a (runtime lib already deals with all the metadata loading, 
>> low level existential, and internal reflection)
>> 
>> then :
>> BUILTIN_LITERAL_CONVERTIBLE_PROTOCOL_(BuiltinBooleanLiteralConvertible)
>> BUILTIN_LITERAL_CONVERTIBLE_PROTOCOL_(BuiltinExtendedGraphemeClusterLiteralConvertible)
>> BUILTIN_LITERAL_CONVERTIBLE_PROTOCOL_(BuiltinFloatLiteralConvertible)
>> ...
>> 
>> can become (or stay as it is but, the point is that they are unified, and 
>> have become a pattern for future extensibility)
>> 
>> BUILTIN_CORE_PROTOCOL_(SwiftBooleanLiteralConvertible)  // btw, they can all 
>> retain the BuiltinXxxxxxxx pattern
>> BUILTIN_CORE_PROTOCOL_(SwiftExtendedGraphemeClusterLiteralConvertible)
>> BUILTIN_CORE_PROTOCOL_(SwiftFloatLiteralConvertible)
>> BUILTIN_CORE_PROTOCOL_(SwiftBottomType)              // one of the the new 
>> guys
>> 
>> 
>> 2) then create  a  enum NoReturn: SwiftBottomType {}  that we learn about 
>> (and name it Never, or …. to match the returning situation. And as time 
>> goes, there may be other synonymous that will be built with the best 
>> possible user facing name for these circumstances.
>> 
>> 
>> When looking at this question and a couple of other related ones, a pattern 
>> should form, whose rational is self evident (I am listing a couple others in 
>> a separate doc just because IMHO it is a somewhat elegant binding for the 
>> low level)
> 
> 
> btw, I know that BUILTIN_LITERAL_CONVERTIBLE_PROTOCOL_ have to be treated 
> differently, but I think it is still possible to use the pattern they form to 
> express other critically essential language notions via Protocols as opposed 
> to contextual keywords (eg .Type .Self ) or some other types of secret 
> hand-shakes.
> 
> For example at the moment they all are statically declared in the compiler, 
> which also means that adding a new one requires recompiling the compiler, or 
> that users cannot follow in the footsteps with their own literal convertibles 
> (ours have to remain on the other side of a possible very smart thing the 
> compiler would learn to do in the future). Which means that nothing says the 
> following cannot be done
> 
> Replace :
> 
> BUILTIN_LITERAL_CONVERTIBLE_PROTOCOL_(BuiltinBooleanLiteralConvertible)
> BUILTIN_LITERAL_CONVERTIBLE_PROTOCOL_(BuiltinExtendedGraphemeClusterLiteralConvertible)
> BUILTIN_LITERAL_CONVERTIBLE_PROTOCOL_(BuiltinFloatLiteralConvertible)
> BUILTIN_LITERAL_CONVERTIBLE_PROTOCOL_(BuiltinIntegerLiteralConvertible)
> ...
> 
> with 
> 
> BUILTIN_CORE_PROTOCOL_(SwiftLiteralConvertible)       // a single core 
> protocol to flag for the compiler the entire literal convertible pattern
> BUILTIN_CORE_PROTOCOL_(SwiftBottomType)               // one of the the new 
> core guys
> 
> BUILTIN_SPECIALISED_PROTOCOL_(BuiltinBooleanLiteralConvertible, 
> SwiftLiteralConvertible)
> BUILTIN_SPECIALISED_PROTOCOL_(BuiltinExtendedGraphemeClusterLiteralConvertible,
>  SwiftLiteralConvertible)
> 
> and then maybe the second type can be opened to us too… or these secondary 
> definitions get out of the c++ code and back into the sodlib .swift code, 
> which means that we can pattern some 
> MyOwnSmartLiteralConvertibleThatISwearWillBehaveLikeYours after this model 
> and have it equally discoverable as the lib's
> 
> 
> reading your code is a very humbling experience.. I just think some 
> additional symmetries might simplify certain things.
> 
> 
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to