[swift-evolution] [Proposal] Change Void meaning

Jens Persson jens at bitcycle.com
Mon Jun 12 15:03:41 CDT 2017


Yes, I agree and I think the behavior of Swift 4 is more consistent than
that of Swift 3(.2) here.

On Mon, Jun 12, 2017 at 9:57 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:

> 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/009bac65/attachment.html>


More information about the swift-evolution mailing list