[swift-evolution] [Proposal] Change Void meaning

Jérémie Girault jeremie.girault at gmail.com
Tue Jun 13 06:09:41 CDT 2017


For clarity and improvement, could you please post a sample where an
ambiguity could happen? I can't think of the issue here.
I think that type-safety can still be conserved.

—
very short reply expected - vsre.info
Jérémie Girault

On 13 juin 2017 at 11:06:54, Florent Bruneau via swift-evolution (
swift-evolution at swift.org) wrote:


> Le 13 juin 2017 à 10:41, Xiaodi Wu via swift-evolution <
swift-evolution at swift.org> a écrit :
>
>> On Tue, Jun 13, 2017 at 3:06 AM, John McCall <rjmccall at apple.com> wrote:
>>> On Jun 13, 2017, at 3:30 AM, Jérémie Girault <jeremie.girault at gmail.com>
wrote:
>>>
>>> Exactly,
>>> The reflexion behind it is:
>>>
>>> - Let's understand that 0110 and other tuple SE are important for the
compiler, we do not want them to rollback
>>> - However we have number of regressions for generics / functional
programmers
>>> - Let’s solve this step by step like a typical problem
>>>
>>> - Step 0 is adressing this Void tuple of size zero :
>>> - Zero is in many problems of CS an edge case, so let’s handle this
case first
>>> - The compiler knows what Void is, and its only value (or non-value)
>>> - It was handled historically by the compiler because of implicit side
effects
>>> - Let’s handle it explicitely with rules in current context
>>> - one effect of the proposal is source compatibility
>>> - but the goal is to build atop and strengthen 0110, 0066 and other
tuple-related SE
>>>
>>
>> There are four difficulties I see with this proposal.
>>
>> The first is that it is a first step that quite clearly does not lead to
anything. It resolves a difficulty with exactly one case of function
composition, but we would need completely different solutions to handle any
of the other compositional regressions of SE-0110.
>>
>> The second is that it's a huge source of complexity for the type system.
The type checker would not be able to do even rudimentary type matching,
e.g. when checking a call, without having first resolved all of the
argument and parameter types to prove that they are not Void. This would
probably render it impossible to type-check many programs without some
ad-hoc rule of inferring that certain types are not Void. It would
certainly make type-checking vastly more expensive.
>>
>> The third is that it is not possible to prevent values of Void from
existing, because (unlike Never, which cannot be constructed) they are
always created by returning from a Void-returning function, and a generic
function can do anything it likes with that value — turn it into an Any,
store it in an Array, whatever. The proposal seems to only consider using
the value as a parameter.
>>
> Hang on, though. If Jérémie is interested only in addressing the issue of
Void as a parameter and his idea can be adequately carried out by inferring
a default value of Void for every parameter of type Void, this should be a
fairly self-contained change, should it not? And would the impact on the
cost of type checking really be vastly greater in that case?
>
> This idea is now rather intriguing to me because it extends beyond just
addressing one symptom of SE-0110. Swift allows us to omit the spelling out
of return types that are Void, it allows warning-free discarding of return
values that are Void, etc. This could add a nice consistency and
rationalize some of the weirdness of passing a value that is stipulated by
the parameter type.
>
>> Finally, it would allow a lot of inadvertent errors with the use of
generic functions, because any argument of unconstrained type could be
accidentally specialized with Void. For example, if you forgot to pass an
argument to this function, it would simply infer T=Void:
>> func append<T>(value: T)
>> It seems more likely that this would lead to unexpected, frustrating
bugs than that this would actually be desired by the programmer. You really
just want this to kick in in more generic situations.
>>
> Hmm, at first glance, that seemed like it could be bad. But if, say, a
particular collection can store an element of type Void, is it so
undesirable to allow `append()` to append Void?

Seems to me the language should go for safety before convenience here. In
John's example you are dealing with a generic function, not a generic type
and having append() being silently resolve to append<Void>(value: Void)
could clearly cause bug with the wrong append() function being called in
some cases (because you may mean `append()` from a parent scope instead of
`append(value: Void)` from the current scope)

In the case of a collection, or any generic type, you can simply provide an
`extension Collection where Element == Void { }` that overloads you
append() function with a no-param version.

>>
>>>> very short reply expected - vsre.info
>> Jérémie Girault
>>
>> On 13 juin 2017 at 00:44:52, Xiaodi Wu (xiaodi.wu at gmail.com) wrote:
>>
>>> On Mon, Jun 12, 2017 at 5:38 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>> On Mon, Jun 12, 2017 at 5:25 PM, Jérémie Girault <
jeremie.girault at gmail.com> wrote:
>>>
>>>
>>>>>> very short reply expected - vsre.info
>>> Jérémie Girault
>>>
>>> On 12 juin 2017 at 23:56:37, Xiaodi Wu (xiaodi.wu at gmail.com) wrote:
>>>
>>>> On Mon, Jun 12, 2017 at 4:47 PM, Jérémie Girault <
jeremie.girault at gmail.com> wrote:
>>>> - Void as arguments is pretty common when using generics, that’s a
core point of this proposal. An maybe that’s why we misunderstood ourselves
(around 0110 / 0066). This proposal addresses arguments.
>>>> - maybe it should be revised around this ? Simple example :
>>>>
>>>> `typealias Callback<T> = (T) -> Void` -> `Callback<Void>` will give
`(Void) => Void`.
>>>>
>>>> It was acceptable before swift4 but no more. However nobody cares
about this `Void` argument and actually we know it’s value. So why let the
developer type it ?
>>>>
>>>> Ah, I see. The purpose of SE-0029...SE-0110 was to make it possible to
distinguish an argument list `(Void)` from an argument list `()`. This does
cause some verbosity where previously users relied on implicit tuple
splatting. Ideally, we would bring back some syntactic sugar to make this
more ergonomic. But, whether or not the spelling is made more
user-friendly, the point here is that _everybody_ should care about this
`Void` argument.
>>> It is still be typechecked and appropriate errors should be reported to
the user so _nobody_ will ignore it.
>>>
>>> But with the proposal the code will be striped out of Void arguments at
compile-time. I think it's a win for the developer on a lot of grounds. The
fact that this proposal integrates with the type-system is also important.
>>>
>>> If you are not comfortable about Void being stripped, we can also
discuss alternatives: someone was suggesting me that it would be possible
to replace :
>>>
>>> ```
>>>
>>> func foo<T, U, V>(t: T, u: U) -> V {
>>>
>>> // do something with t and u
>>>
>>> // return some V
>>>
>>> }
>>>
>>> ```
>>>
>>> with
>>>
>>> ```
>>>
>>> func foo<Void, Int, String>(u: Int) -> String { let t = ()
>>>
>>> // do something with t and u
>>>
>>> // return some V
>>>
>>> }
>>>
>>> ```
>>>
>>> or
>>>
>>> ```
>>>
>>> func foo<Void, Int, String>(t: Void = (), u: Int) -> String {
>>>
>>> // do something with t and u
>>>
>>> // return some V
>>>
>>> }
>>>
>>> ```
>>>
>>> I don’t know what you would consider more effective or elegant (at an
implementation level) but it’s the same result for the developper.
>>>
>>>
>>> Ah, but I think I catch your drift with the last example. Is this a
more general point that the compiler should treat every parameter of type
Void as having an implied default value of Void? That would be an
interesting idea.
>>>
>>> What is the goal of such changes? Is it to allow you to write `foo()`
instead of `foo(())` for a function `foo` of type `(T) -> Void`?
>>>
>>> If so, then I think what you're seeking to do is reverse SE-0066 (as
Vladimir points out), which explicits details how it's is an intentional
change to require such a spelling. I think you're starting from the premise
that this is unintended or undesirable, when in fact it is deliberate and
approved.
>>>
>>> It is also, unless I'm mistaken, not the issue that was raised
initially with respect to SE-0110, which had to do with the extra
boilerplate of destructuring a tuple inside a closure, something that was
not so obvious before implementation.
>>>
>>>> My point here is that `Void` should be “striped” by “reducing”
argument list signatures.
>>>>
>>>>>>>> very short reply expected - vsre.info
>>>> Jérémie Girault
>>>>
>>>> On 12 juin 2017 at 19:15:18, John McCall (rjmccall at apple.com) wrote:
>>>>
>>>>>
>>>>>> On Jun 12, 2017, at 4:48 AM, Jérémie Girault via swift-evolution <
swift-evolution at swift.org> wrote:
>>>>>>
>>>>>> Hi here,
>>>>>>
>>>>>> As I tested swift4 in xcode9b1 I noticed a lot of regressions about
tuples usage.
>>>>>>
>>>>>> After documenting myself about the changes which happened, I thought
that they could be improved. Instead of fighting these propositions (which
make sense), I wanted create a few proposal which would improve these
recent changes with a few simple rules.
>>>>>>
>>>>>> My propositions are based on the recent decisions and in the
continuation of SE-0110. The first one is about Void.
>>>>>> Void is historically defined as the type of the empty tuple. The
reason of this is that arguments were initially considered as tuple.
>>>>>
>>>>> The dominant consideration here was always return types, not
parameters. I'm not sure there was ever much point in writing Void in a
parameter list, but whatever reasons there were surely vanished with
SE-0066.
>>>>>
>>>>> Note that 'void' in C was originally exclusively a return type. ANSI
gave it a new purpose it with void*, but the meaning is totally unrelated.
>>>>>
>>>>> John.
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 
Florent Bruneau

_______________________________________________
swift-evolution mailing list
swift-evolution at swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170613/a5d9b7b1/attachment.html>


More information about the swift-evolution mailing list