They may be semantically distinct and part of the type system, but they are not types. I don’t think they should be given the privilege of overloading, but this is a separate discussion.
~Robert Widmann > On Jun 13, 2017, at 11:00 AM, John McCall <[email protected]> wrote: > >> On Jun 13, 2017, at 1:48 PM, Beta <[email protected] >> <mailto:[email protected]>> wrote: >> I would like to note that overloading on inout is a code smell and something >> that should be removed in a future version of the language. inout is not a >> type, it’s a SIL type residency annotation. > > Uh, no, inout arguments are semantically extremely different from by-value > arguments, and this is very much part of the type system. > > John. > >> >> ~Robert Widmann >> >>> On Jun 13, 2017, at 10:40 AM, Xiaodi Wu via swift-evolution >>> <[email protected] <mailto:[email protected]>> wrote: >>> >>> Note that “inout Void” is a distinct type from “Void”; it is not possible >>> to specify a default value for an inout Void parameter even explicitly >>> (“error: cannot pass immutable value of type ()...”), so naturally it >>> cannot be done implicitly either. >>> On Tue, Jun 13, 2017 at 12:29 Jens Persson <[email protected] >>> <mailto:[email protected]>> wrote: >>> The std lib swap could perhaps be an interesting example to consider: >>> public func swap<T>(_ a: inout T, _ b: inout T) >>> >>> What would happen with that? >>> Will inout arguments be an exception to the rule of Void getting a default >>> value, and if so, what would the effects of that be? >>> Or would it somehow be allowed to call swap()? >>> Or is there a third alternative? >>> /Jens >>> >>> On Tue, Jun 13, 2017 at 7:15 PM, John McCall via swift-evolution >>> <[email protected] <mailto:[email protected]>> wrote: >>> >>>> On Jun 13, 2017, at 4:41 AM, Xiaodi Wu <[email protected] >>>> <mailto:[email protected]>> wrote: >>>> >>>> On Tue, Jun 13, 2017 at 3:06 AM, John McCall <[email protected] >>>> <mailto:[email protected]>> wrote: >>>>> On Jun 13, 2017, at 3:30 AM, Jérémie Girault <[email protected] >>>>> <mailto:[email protected]>> 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? >>> >>> If the proposal was phrased in terms of defaults, e.g. "trailing parameters >>> do not require a matching argument if they have Void type", then yes, that >>> would be implementable because it still admits a "local" reduction on call >>> constraints, one which does not need to immediately reason about the actual >>> types of arguments. It is not clear that this rule allows function >>> compositions of the sort that Jérémie is looking for, though. >>> >>> Anyway, that is not the proposal; the proposal is that parameters — in any >>> position — are simply removed from the parameter sequence if they have Void >>> type. In order to allow composition (i.e. f(g(x)), where g: X -> Void), >>> you then need a matching rule that arguments are dropped from the argument >>> sequence (for purposes of type-checking) if they have Void type. Either of >>> these rules is sufficient to turn the reduction of function-type matches >>> into an extremely messy combinatoric matching problem where e.g. (τ0, Int) >>> can be passed to a function taking (Int, τ1) if we can decide that τ0 == τ1 >>> == Void. >>> >>>> 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? >>> >>> append on a Collection is not an unconstrained generic; its parameter type >>> is determined by the type of the collection. Perhaps this was a >>> poorly-chosen example. >>> >>> John. >>> >>>> >>>> >>>> John. >>>> >>>>> >>>>> — >>>>> very short reply expected - vsre.info <http://vsre.info/> >>>>> Jérémie Girault >>>>> >>>>> On 13 juin 2017 at 00:44:52, Xiaodi Wu ([email protected] >>>>> <mailto:[email protected]>) wrote: >>>>> >>>>>> On Mon, Jun 12, 2017 at 5:38 PM, Xiaodi Wu <[email protected] >>>>>> <mailto:[email protected]>> wrote: >>>>>> On Mon, Jun 12, 2017 at 5:25 PM, Jérémie Girault >>>>>> <[email protected] <mailto:[email protected]>> wrote: >>>>>> >>>>>> >>>>>> — >>>>>> very short reply expected - vsre.info <http://vsre.info/> >>>>>> Jérémie Girault >>>>>> >>>>>> On 12 juin 2017 at 23:56:37, Xiaodi Wu ([email protected] >>>>>> <mailto:[email protected]>) wrote: >>>>>> >>>>>>> On Mon, Jun 12, 2017 at 4:47 PM, Jérémie Girault >>>>>>> <[email protected] <mailto:[email protected]>> 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 <http://vsre.info/> >>>>>>> Jérémie Girault >>>>>>> >>>>>>> On 12 juin 2017 at 19:15:18, John McCall ([email protected] >>>>>>> <mailto:[email protected]>) wrote: >>>>>>> >>>>>>>> >>>>>>>>> On Jun 12, 2017, at 4:48 AM, Jérémie Girault via swift-evolution >>>>>>>>> <[email protected] <mailto:[email protected]>> 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 >>> [email protected] <mailto:[email protected]> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] <mailto:[email protected]> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
