[swift-evolution] [Proposal] Change Void meaning

Xiaodi Wu xiaodi.wu at gmail.com
Mon Jun 12 14:57:52 CDT 2017


On Mon, Jun 12, 2017 at 2:49 PM, Jens Persson <jens at bitcycle.com> wrote:

> Just adding this here for reference:
> func foo(_: Void) {}
> func bar() {}
> // All these compile in Swift 3:
> foo()
> foo(())
> bar()
> bar(())
> // But only these two compile in Swift 4:
> foo(())
> bar()
>

So, `foo` takes one argument of type `()` but `bar` takes zero arguments.
The expectation that you can call a function with a single tuple of some
arity instead of the declared number of arguments is fulfilled by implicit
tuple splatting, which is intentionally removed. This has nothing to do
with what `Void` means; the single argument could be `Int` or `String` or
`Data`.


On Mon, Jun 12, 2017 at 9:44 PM, Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> On Mon, Jun 12, 2017 at 2:32 PM, Jérémie Girault <
>> jeremie.girault at gmail.com> wrote:
>>
>>> @xiaodi
>>> I disagree on many points, for example what is the type of x when we
>>> type `let x = *Void` ?
>>>
>>
>> That would not be a legal statement. Exploding a tuple is an operation
>> that only makes sense inside an argument list. Likewise `let x = &Void`
>> will not compile.
>>
>>
>>> This is the essence of the problem and this proposition wants to solve
>>> this.
>>>
>>> The regression is due to both reason combined : typealias Void = () AND
>>> SE-0110
>>>
>>> My proposition is to change the meaning of Void from () to “something
>>> else” that is type-compatible with SE-0110 (and splatting in the future).
>>>
>>
>> I'm not sure I understand your motivation. Void is just a typealias. If
>> tomorrow Void meant something else, all functions must still return (), and
>> there is still no implicit tuple splatting.
>>
>>
>>> If you want an example of the changes needed to migrate to swift4, just
>>> look at the 42 files of handling parenthesis PR of RxSwift needed for
>>> swift4 upgrade : https://github.com/ReactiveX/RxSwift/pull/1282/files
>>>
>>
>> Indeed, that's the result of SE-0110; these parentheses are needed
>> because there is no implicit tuple splatting. They would be required even
>> if `Void` did not exist in the language at all.
>>
>>
>>>
>>>>>> very short reply expected - vsre.info
>>> Jérémie Girault
>>>
>>> On 12 juin 2017 at 21:18:06, Xiaodi Wu (xiaodi.wu at gmail.com) wrote:
>>>
>>> On Mon, Jun 12, 2017 at 2:05 PM, David Hart <david at hartbit.com> wrote:
>>>
>>>>
>>>> On 12 Jun 2017, at 19:25, Xiaodi Wu via swift-evolution <
>>>> swift-evolution at swift.org> wrote:
>>>>
>>>> Unfortunately, I think this proposal appears to be mistaken as to this
>>>> key premise: Void was never (IIUC) meant to model the absence of arguments;
>>>> it is a type with one possible value.
>>>>
>>>> If I recall, a number of conversations have been raised about Void
>>>> being a typealias of (), and the definitive response has been that this
>>>> falls into the ship-has-sailed category of out-of-scope changes.
>>>>
>>>> More generally, the recent spate of complaints about regressions to a
>>>> particular coding style have to do with loss of implicit tuple splatting,
>>>> the cure for which is a proper implementation of tuple splatting, not
>>>> poking holes into settled parts of the type system.
>>>>
>>>>
>>>> But you can’t deny that SE-0110 has also caused regressions in the use
>>>> of Void as generic argument because Void is modelled as the empty tuple.
>>>>
>>>
>>> I'm not sure I understand this statement. Void is a synonym for the
>>> empty tuple, and that hasn't ever changed, so it can't be the root cause of
>>> any regressions.
>>>
>>>
>>>> And tuple splatting will not fix those regressions.
>>>>
>>>
>>> How come? If `*` is the splat operator, then it would be legal to call a
>>> function `foo` that takes no arguments with `foo(*Void)`; if implicit tuple
>>> splatting returns in fully implemented form, then it would be legal to call
>>> it once again with `foo(Void)`.
>>>
>>> And contrary to what some people might think, this is not an
>>>> “edge-case”. Most useful monads modelled with generics have good reasons to
>>>> use Void:
>>>>
>>>> *The Result<T> monad:* Result<Void> represents the result of an
>>>> operation with no return value
>>>> *The Promise<T> monad:* Promise<Void> represents the result of an
>>>> asynchronous operation with no return value
>>>> *The Observable<T> monad (in functional reactive programming):*
>>>> Observable<Void> represents a stream of events with no values
>>>>
>>>> I use all three monads in my code and I’ve had to modify a lot of code
>>>> when migrating to Swift 4 beta1 because of Void.
>>>>
>>>
>>> Can you give examples of the modifications needed during migration? From
>>> here, I can only see that the reason any code needs modification is the
>>> complete removal of implicit tuple splatting. Nothing has changed about
>>> Void being a synonym for the empty tuple; even if you rename Void,
>>> functions will still return () by some other name, and unless there is
>>> tuple splatting in some form, the migration you performed is inevitable.
>>>
>>> On Mon, Jun 12, 2017 at 12:15 John McCall via swift-evolution <
>>>> swift-evolution at swift.org> 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
>>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>>>
>>>>
>>>
>>
>> _______________________________________________
>> 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/20170612/40c131cb/attachment.html>


More information about the swift-evolution mailing list