<div dir="ltr">On Tue, Dec 27, 2016 at 1:27 PM, Adrian Zubarev <span dir="ltr"><<a href="mailto:adrian.zubarev@devandartist.com" target="_blank">adrian.zubarev@devandartist.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div class="gmail-m_-8966874194301951949bloop_markdown"><p>I’m not sure I’m following your point here. Could you provide a simple and short code sample please?</p></div></div></blockquote><div>So I guess I'm having trouble understanding the motivating use case for your idea. As I understand it, you wish to make sure that each constraint (a, b, c, etc.) is set at most once, at compile time. The way to do this in Swift is to have a type T like this [I'm writing freehand, so pardon any typos]:</div><div><br></div><div>```</div><div>struct T {</div><div> let a, b, c: Int?</div><div> init(a: Int? = nil, b: Int? = nil, c: Int? = nil) {</div><div> self.a = a; self.b = b; self.c = c</div><div> }</div><div>}</div><div>```</div><div><br></div><div>Now, any value `x` will have set constraints a, b, and c at most once. If the issue is that you don't know a, b, and c all at the same time, you initialize a temporary `x`, then copy the already-set constraints to another `y` when another constraint is known; the constraints in `y` will have been set at most once.</div><div><br></div><div>If I understand it correctly, you want to guarantee at compile time that a user never makes a new `y` from `x` by invoking some arbitrary method `foo()` twice in the same scope, and you're therefore proposing a stateful static type system? I don't quite understand why. As long as I know the constraints set on `x`, I can always make a new value that copies over constraints from `x`, resulting in a value identical in every way to the `y` that I could get from `foo()`. In code:</div><div><br></div><div>```</div><div>// Given a, b, c, d</div><div>let x = T(a)</div><div>let y = x.addingBConstraint(withValue: b)</div><div>let z = y.addingCConstraint(withValue: c)</div><div><br></div><div>// You want the following line to be forbidden at compile time<br></div><div>let w = z.addingCConstraint(withValue: d)</div><div><br></div><div>// But I can always write instead</div><div>let w = T(a, b, d)</div><div><br></div><div>// Or</div><div>let w = T(z.a, z.b, d)</div><div><br></div><div>// And `w` would be in every way identical to the previous forbidden line</div><div>// Why do you need the type system to keep track of how `w` was created?</div><div>```</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div class="gmail-m_-8966874194301951949bloop_markdown"><p><span style="font-family:helvetica,arial;font-size:13px">-- </span></p></div><div class="gmail-m_-8966874194301951949bloop_original_html"><span class="gmail-"><div id="gmail-m_-8966874194301951949bloop_sign_1482863151004794112" class="gmail-m_-8966874194301951949bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">Adrian Zubarev<br>Sent with Airmail</div></div> <br></span><div><div class="gmail-h5"><p class="gmail-m_-8966874194301951949airmail_on">Am 27. Dezember 2016 um 19:24:15, Xiaodi Wu (<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>) schrieb:</p> <blockquote type="cite" class="gmail-m_-8966874194301951949clean_bq"><span><div><div></div><div>
What do you think of using a value type as a subtype, and having an
initializer that supplies defaults? It can only be used once, and
after that you have to create a new value. Does that not satisfy
your compile-time needs?<br>
<div class="gmail_quote">
<div dir="ltr">On Tue, Dec 27, 2016 at 13:20 Adrian Zubarev
<<a href="mailto:adrian.zubarev@devandartist.com" target="_blank">adrian.zubarev@devandartist.<wbr>com</a>>
wrote:<br></div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806bloop_markdown gmail-m_-8966874194301951949gmail_msg">
<p class="gmail-m_-8966874194301951949gmail_msg">Do you have any suggestions on how this area
could be solved differently and less complex as it seems to be
here? :) I’m open minded and I’d really appreciate if we’d have
some language support for this problem.</p>
<p class="gmail-m_-8966874194301951949gmail_msg"></p>
</div>
<div class="gmail-m_-8966874194301951949m_8254029652668701806bloop_original_html gmail-m_-8966874194301951949gmail_msg">
</div>
</div>
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806bloop_original_html gmail-m_-8966874194301951949gmail_msg">
<div id="gmail-m_-8966874194301951949m_8254029652668701806bloop_customfont" style="font-family:helvetica,arial;font-size:13px;color:rgb(0,0,0);margin:0px" class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></div>
<br class="gmail-m_-8966874194301951949gmail_msg">
<div id="gmail-m_-8966874194301951949m_8254029652668701806bloop_sign_1482862693008625920" class="gmail-m_-8966874194301951949m_8254029652668701806bloop_sign gmail-m_-8966874194301951949gmail_msg">
<div style="font-family:helvetica,arial;font-size:13px" class="gmail-m_-8966874194301951949gmail_msg">-- <br class="gmail-m_-8966874194301951949gmail_msg">
Adrian Zubarev<br class="gmail-m_-8966874194301951949gmail_msg">
Sent with Airmail</div>
</div>
<br class="gmail-m_-8966874194301951949gmail_msg"></div>
</div>
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806bloop_original_html gmail-m_-8966874194301951949gmail_msg">
<p class="gmail-m_-8966874194301951949m_8254029652668701806airmail_on gmail-m_-8966874194301951949gmail_msg">Am 27.
Dezember 2016 um 18:49:22, Xiaodi Wu (<a href="mailto:xiaodi.wu@gmail.com" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">xiaodi.wu@gmail.com</a>) schrieb:</p>
<blockquote type="cite" class="gmail-m_-8966874194301951949m_8254029652668701806clean_bq gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949gmail_msg"></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">TBH, I think you're
trying to solve this problem in a very complicated way. What you're
describing screams out for its own value subtype with let variables
and an initializer that will provide defaults. I'm skeptical such a
complicated design as you propose is necessary to achieve what you
want.<br class="gmail-m_-8966874194301951949gmail_msg">
<br class="gmail-m_-8966874194301951949gmail_msg"></span>
<div class="gmail_quote gmail-m_-8966874194301951949gmail_msg">
<div dir="ltr" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">On Tue,
Dec 27, 2016 at 05:25 Adrian Zubarev via swift-evolution
<<a href="mailto:swift-evolution@swift.org" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:<br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<blockquote class="gmail_quote gmail-m_-8966874194301951949gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495bloop_markdown gmail-m_-8966874194301951949gmail_msg">
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">Okay now I see your
point there. :) Thank you Xiaodi and Tony.</span></p>
<hr class="gmail-m_-8966874194301951949gmail_msg">
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">It’s an interesting
approach you have there, but I see another problem with
<code class="gmail-m_-8966874194301951949gmail_msg">Self</code> and <code class="gmail-m_-8966874194301951949gmail_msg">-
ProtocolName</code>. <code class="gmail-m_-8966874194301951949gmail_msg">Self</code> does not
refer to the current type returned from the protocol member.
SE–0068 might help there, but as soon we’re working with non-final
classes it will be problematic again.</span></p>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">That means something
like this will be possible <code class="gmail-m_-8966874194301951949gmail_msg">constraint.x(1).y(1).x(2)</code>, which by solving the
main problem of this topic we’d like to avoid.</span></p>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">We’d need a way to
subtract a protocol from the returned type + the ability of keeping
<code class="gmail-m_-8966874194301951949gmail_msg">T</code> only members.</span></p>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">As for <code class="gmail-m_-8966874194301951949gmail_msg">T : P1 & P2 & P3</code>, <code class="gmail-m_-8966874194301951949gmail_msg">T - P1</code> should return <code class="gmail-m_-8966874194301951949gmail_msg">T +
P2 & P3</code>, because it’s what the user would logically
assume there. The next chain needs to remember <code class="gmail-m_-8966874194301951949gmail_msg">- P1</code> on that path, so the result for the
followed reduction of <code class="gmail-m_-8966874194301951949gmail_msg">- P3</code> would be
equivalent to <code class="gmail-m_-8966874194301951949gmail_msg">T - P1 & P3</code> =
<code class="gmail-m_-8966874194301951949gmail_msg">T + P2</code>.</span></p>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">As you already
mentioned, one would assume that we might be able to cast back to
<code class="gmail-m_-8966874194301951949gmail_msg">T</code> from <code class="gmail-m_-8966874194301951949gmail_msg">T -
P1 & P3</code>. I think this leads us to the right direction
where we should realize that we should escape from <code class="gmail-m_-8966874194301951949gmail_msg">T</code> in general. That means that the return type
should somehow create a new subtraction type, which can be reduced
further by member chaining or escaped similar to what I wrote in
the original post.</span></p>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">We’d need a new type
or keyword that refers to the current (reduced) type. Let’s call it
<code class="gmail-m_-8966874194301951949gmail_msg">Current</code> instead of <code class="gmail-m_-8966874194301951949gmail_msg">Self</code>. Furthermore we’d need a concrete result
type, to be able to pass the result value around. Let’s call the
latter type <code class="gmail-m_-8966874194301951949gmail_msg">Subtraction<T></code>.</span></p>
<pre class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><code class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495swift gmail-m_-8966874194301951949gmail_msg">protocol WidthConstrainable {
func width(_ v: CGFloat) -> Subtraction<Current – WidthConstrainable>
}
protocol HeightConstrainable {
func height(_ v: CGFloat) -> Subtraction<Current – HeightConstrainable>
}
protocol XConstrainable {
func x(_ v: CGFloat) -> Subtraction<Current – XConstrainable>
}
protocol YConstrainable {
func y(_ v: CGFloat) -> Subtraction<Current – YConstrainable>
}
struct Constraint: WidthConstrainable, HeightConstrainable, XConstrainable, YConstrainable {
...
}
</code></span></pre>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><code class="gmail-m_-8966874194301951949gmail_msg">Subtraction<T></code> could be a similar type,
like we’re proposing to change the metatypes from <code class="gmail-m_-8966874194301951949gmail_msg">T.Type/Protocol</code> to <code class="gmail-m_-8966874194301951949gmail_msg">Type<T></code> and <code class="gmail-m_-8966874194301951949gmail_msg">AnyType<T></code>. That means that it would know
all the members of <code class="gmail-m_-8966874194301951949gmail_msg">Current</code> without
the subtrahend. Each further member chain would create ether a
nested <code class="gmail-m_-8966874194301951949gmail_msg">Subtraction<Subtraction<T -
P1> - P2></code> or a flattened type like <code class="gmail-m_-8966874194301951949gmail_msg">Subtraction<T - P1 & P2></code>.</span></p>
<pre class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><code class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495swift gmail-m_-8966874194301951949gmail_msg">let constraint = Constraint()
let a: Subtraction<Constraint - XConstrainable> = constraint.x(1)
let b: Subtraction<Subtraction<<wbr>Constraint - XConstrainable> - YConstrainable> = a.y(2)
let c: Subtraction<Subtraction<<wbr>Subtraction<Constraint - XConstrainable> - YConstrainable> - WidthConstrainable> = b.width(100)
_ = constraint.x(1).y(2).width(<wbr>100)
</code></span></pre>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">That way we could even
remove the new <code class="gmail-m_-8966874194301951949gmail_msg">-</code> operator and use
generics parameter list instead. Maybe instead of <code class="gmail-m_-8966874194301951949gmail_msg">Subtraction</code> we could call the new type
<code class="gmail-m_-8966874194301951949gmail_msg">Difference<T></code></span></p>
<pre class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><code class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495swift gmail-m_-8966874194301951949gmail_msg">type Difference<Minuend, Subtrahend> : Minuend - Subtrahend { … } // should know everything `Minuend` has, but exclude everything from `Subtrahend`
struct Constraint: WidthConstrainable, HeightConstrainable, XConstrainable, YConstrainable {
func width(_ v: CGFloat) -> Difference<Current, WidthConstrainable> {
var copy = self
copy.width = v
return Difference(copy)
}
func height(_ v: CGFloat) -> Difference<Current, HeightConstrainable> { … }
func x(_ v: CGFloat) -> Difference<Current, XConstrainable> { … }
func y(_ v: CGFloat) -> Difference<Current, YConstrainable> { … }
}
</code></span></pre>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">What do you guys think
about this approach? :)</span></p>
<p class="gmail-m_-8966874194301951949gmail_msg"></p>
</div>
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495bloop_original_html gmail-m_-8966874194301951949gmail_msg">
</div>
</div>
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495bloop_original_html gmail-m_-8966874194301951949gmail_msg">
<div id="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495bloop_customfont" style="font-family:helvetica,arial;font-size:13px;color:rgb(0,0,0);margin:0px" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span>
<div id="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495bloop_sign_1482828564757652992" class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495bloop_sign gmail-m_-8966874194301951949gmail_msg">
<div style="font-family:helvetica,arial;font-size:13px" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">-- <br class="gmail-m_-8966874194301951949gmail_msg">
Adrian Zubarev<br class="gmail-m_-8966874194301951949gmail_msg">
Sent with Airmail</span></div>
</div>
<span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
</div>
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495bloop_original_html gmail-m_-8966874194301951949gmail_msg">
<p class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495airmail_on gmail-m_-8966874194301951949gmail_msg">
<span class="gmail-m_-8966874194301951949gmail_msg">Am 26. Dezember 2016 um 17:17:29, Tony
Allevato (<a href="mailto:allevato@google.com" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">allevato@google.com</a>) schrieb:</span></p>
<blockquote type="cite" class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495clean_bq gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949gmail_msg"></div>
<div class="gmail-m_-8966874194301951949gmail_msg">
<div dir="ltr" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">Xiaodi's point is really
important—being able to express the notions simultaneously that "T
has method a()" and "T does not have method a()" would break the
type system.</span></span>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">Instead of focusing
on the proposed syntax, let's consider the problem you're trying to
solve. It sounds like what you're asking for could be expressed
more cleanly with a richer protocol algebra that supported
subtraction. It wouldn't be quite as automatic as what you propose,
but it would feel like a more natural extension of the type system
if you could do something like below, and would avoid combinatorial
explosion of protocol types (you go from O(n!) to O(n) things you
actually have to define concretely):</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">```</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">protocol
WidthConstrainable {</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"> func width(_
v: CGFloat) -> Self – WidthConstrainable</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">}</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">protocol
HeightConstrainable {</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"> func height(_
v: CGFloat) -> Self – HeightConstrainable</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">}</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">protocol
XConstrainable {</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"> func x(_ v:
CGFloat) -> Self – XConstrainable</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">}</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">protocol
YConstrainable {</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"> func y(_ v:
CGFloat) -> Self – YConstrainable</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">}</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">struct Constraint:
WidthConstrainable, HeightConstrainable, XConstrainable,
YConstrainable {</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">
...</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">}</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">```</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">If a type X is just
a union or protocols (for example, X: WidthConstrainable &
HeightConstrainable & XConstrainable & YConstrainable), the
subtraction (X – something) is easy to define. It's either valid if
the subtrahend is present in the set, or it's invalid (and
detectable at compile time) if it's not.</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">But there are still
some rough edges: what does it mean when a concrete type is
involved? Let's say you have T: P1 & P2 & P3, and you write
(T – P1). That could give you a type that contains all the members
of T except those in P1, which would be the members in P2, P3, and
any that are defined directly on T that do not come from protocol
conformances.</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">But what is the
relationship between types T and (T – P1)? (T – P1) being a
supertype of T seems fairly straightforward—any instance of T can
be expressed as (T – P1). But if I have an instance of type (T –
P1), should I be able to cast that back to T? On the one hand, why
not? I can obviously only get (T – P1) by starting with T at some
point, so any instance of (T – P1) must *also* be an instance of T.
So that implies that T is a supertype of (T – P1). In other words,
they're supertypes of each other, without being the same type? That
would be a first in Swift's type system, I believe. And if we allow
the cast previously mentioned, that effectively circumvents the
goal you're trying to achieve. (We could argue that you'd have to
use a force-cast (as!) in this case.)</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">This could be worked
around by forbidding subtraction from concrete types and reducing T
to the union of its protocols before performing the subtraction. In
that case, (T – P1) would equal P2 & P3. But that relationship
is still a little wonky: in that case, (T – P1) would also not
contain any members that are only defined on T, even though the
expression (T – P1) implies that they should. You would have to
make that reduction explicit somehow in order for that to not
surprise users (require writing something like `#protocols(of: T) –
P1`?), and it leaves a certain subset of possible type expressions
(anything that wants members defined on T without members of a
protocol) unexpressible.</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">I actually glossed
over this earlier by writing "..." in the struct body. If I defined
`width(_:)` there, what would my return type be? We currently
forbid `Self` in that context. Would `Self – WidthConstrainable` be
allowed? Would I have to use the new protocol-reduction operator
above? More details that would have to be worked out.</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">Protocol inheritance
would pose similar questions. If you have this:</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">```</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">protocol P1
{}</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">protocol P2: P1
{}</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">```</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">What is the
subtype/supertype relationship between P2 and (P2 – P1)? It's the
same situation we had with a concrete type. Maybe you just can't
subtract a super-protocol without also subtracting its lowest
sub-protocol from the type?</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">My PL type theory
knowledge isn't the deepest by any means, but if something like
this was workable, I think it would be more feasible and more
expressive than the member permutation approach. And that being
said, this is probably a fairly narrow use case that wouldn't
warrant the complexity it would bring to the type system to make it
work.</span></div>
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
</div>
<span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span>
<div class="gmail_quote gmail-m_-8966874194301951949gmail_msg">
<div dir="ltr" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">On Mon,
Dec 26, 2016 at 7:03 AM Xiaodi Wu via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:<br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<blockquote class="gmail_quote gmail-m_-8966874194301951949gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<span class="gmail-m_-8966874194301951949gmail_msg">Should the following compile?<br class="gmail-m_-8966874194301951949gmail_msg">
<br class="gmail-m_-8966874194301951949gmail_msg">
let bar = foo.a()<br class="gmail-m_-8966874194301951949gmail_msg">
func f(_ g: T) {<br class="gmail-m_-8966874194301951949gmail_msg">
_ = g.a()<br class="gmail-m_-8966874194301951949gmail_msg">
}<br class="gmail-m_-8966874194301951949gmail_msg">
f(bar)<br class="gmail-m_-8966874194301951949gmail_msg">
<br class="gmail-m_-8966874194301951949gmail_msg">
If so, your proposal cannot guarantee each method is called only
once. If not, how can bar be of type T?<br class="gmail-m_-8966874194301951949gmail_msg">
<br class="gmail-m_-8966874194301951949gmail_msg"></span>
<div class="gmail_quote gmail-m_-8966874194301951949gmail_msg">
<div dir="ltr" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">On Mon,
Dec 26, 2016 at 06:30 Adrian Zubarev <<a href="mailto:adrian.zubarev@devandartist.com" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">adrian.zubarev@devandartist.<wbr>com</a>> wrote:<br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<blockquote class="gmail_quote gmail-m_-8966874194301951949gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_markdown gmail-m_-8966874194301951949gmail_msg">
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">I think I revise what
I said about value semantics in my last post.</span></p>
<pre class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><code class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355swift gmail-m_-8966874194301951949gmail_msg">let chain: T = foo.a()
let new = chain
new. // should not see `a` here
</code></span></pre>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">It’s more something
like a local scoped chain. I’m not sure how to call it correctly
here. I’m not a native English speaker. =)</span></p>
<p class="gmail-m_-8966874194301951949gmail_msg"></p>
</div>
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_original_html gmail-m_-8966874194301951949gmail_msg">
</div>
</div>
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_original_html gmail-m_-8966874194301951949gmail_msg">
<div id="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_customfont" style="font-family:helvetica,arial;font-size:13px;color:rgb(0,0,0);margin:0px" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span>
<div id="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_sign_1482751593527631872" class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_sign gmail-m_-8966874194301951949gmail_msg">
<div style="font-family:helvetica,arial;font-size:13px" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">-- <br class="gmail-m_-8966874194301951949gmail_msg">
Adrian Zubarev<br class="gmail-m_-8966874194301951949gmail_msg">
Sent with Airmail</span></div>
</div>
<span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
</div>
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_original_html gmail-m_-8966874194301951949gmail_msg">
<p class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355airmail_on gmail-m_-8966874194301951949gmail_msg">
<span class="gmail-m_-8966874194301951949gmail_msg">Am 26. Dezember 2016 um 12:11:23, Adrian
Zubarev (<a href="mailto:adrian.zubarev@devandartist.com" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">adrian.zubarev@devandartist.<wbr>com</a>)
schrieb:</span></p>
<blockquote type="cite" class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355clean_bq gmail-m_-8966874194301951949gmail_msg">
<div style="word-wrap:break-word" class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949gmail_msg"></div>
<div class="gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_markdown gmail-m_-8966874194301951949gmail_msg">
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">By ‘calling once’ I meant, calling once at a single
permutation chain. If the chain is escaped or followed by a
non-permuting member that returns the same protocol, you’d have the
ability to use all members at the starting point of the new
chain.</span></span></p>
<pre class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><code class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355swift gmail-m_-8966874194301951949gmail_msg">permuting protocol T {
func a()
func b()
func c()
func d()
}
var foo: T = …
func boo(_ val: T) -> U {
// Here val escapes the chain and creates a new one
// That means that you can create a local permutation chain here again
val.a() // we can use `a` here
return …
}
boo(foo.a()) // a is immediately invoked here
</code></span></pre>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">I imagine this keyword
to follow value semantics, so that any possible mutation is handled
locally with a nice extra ability of permutation member
chaining.</span></p>
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">Did I understood your
point correctly here?</span></p>
<hr class="gmail-m_-8966874194301951949gmail_msg">
<p class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">Sure the idea needs to
be more fleshed out, but I’m curious if that’s something that we
might see in Swift one day. :)</span></p>
</div>
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_original_html gmail-m_-8966874194301951949gmail_msg">
<div id="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_customfont" style="font-family:helvetica,arial;font-size:13px;color:rgb(0,0,0);margin:0px" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span></div>
<span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span>
<div id="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_sign_1482749838336907008" class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_sign gmail-m_-8966874194301951949gmail_msg">
<div style="font-family:helvetica,arial;font-size:13px" class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg">-- <br class="gmail-m_-8966874194301951949gmail_msg">
Adrian Zubarev<br class="gmail-m_-8966874194301951949gmail_msg">
Sent with Airmail</span></div>
</div>
<span class="gmail-m_-8966874194301951949gmail_msg"><br class="gmail-m_-8966874194301951949gmail_msg"></span>
<p class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355airmail_on gmail-m_-8966874194301951949gmail_msg">
<span class="gmail-m_-8966874194301951949gmail_msg">Am 26. Dezember 2016 um 11:50:50, Xiaodi Wu
(<a href="mailto:xiaodi.wu@gmail.com" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">xiaodi.wu@gmail.com</a>) schrieb:</span></p>
<blockquote type="cite" class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355clean_bq gmail-m_-8966874194301951949gmail_msg">
<div class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><span class="gmail-m_-8966874194301951949gmail_msg"><span style="color:rgb(0,0,0);font-family:'helvetica neue',helvetica;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline" class="gmail-m_-8966874194301951949gmail_msg">Given `foo: T` and methods a(), b(), c(), d(),
each of which can only be called once, how can the return value of
these methods be represented in the type system?</span><br style="color:rgb(0,0,0);font-family:'helvetica neue',helvetica;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail-m_-8966874194301951949gmail_msg">
<br style="color:rgb(0,0,0);font-family:'helvetica neue',helvetica;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail-m_-8966874194301951949gmail_msg">
<span style="color:rgb(0,0,0);font-family:'helvetica neue',helvetica;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);float:none;display:inline" class="gmail-m_-8966874194301951949gmail_msg">That is, if `foo.a()` can be passed as an
argument to an arbitrary function of type `(T) -> U`, either the
function cannot immediately invoke a(), in which case foo is not of
type T, or it can immediately invoke a(), in which case your
keyword does not work.</span></span></span></div>
</blockquote>
</div>
<div class="gmail-m_-8966874194301951949m_8254029652668701806m_-8810590392941529495m_-3067540519206532711m_2486499801731300355bloop_markdown gmail-m_-8966874194301951949gmail_msg">
</div>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
______________________________<wbr>_________________<br class="gmail-m_-8966874194301951949gmail_msg">
swift-evolution mailing list<br class="gmail-m_-8966874194301951949gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail-m_-8966874194301951949gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br class="gmail-m_-8966874194301951949gmail_msg">
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
______________________________<wbr>_________________<br class="gmail-m_-8966874194301951949gmail_msg">
swift-evolution mailing list<br class="gmail-m_-8966874194301951949gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail-m_-8966874194301951949gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail-m_-8966874194301951949gmail_msg" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br class="gmail-m_-8966874194301951949gmail_msg">
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</div></div></span></blockquote></div></div></div><div class="gmail-m_-8966874194301951949bloop_markdown"><p></p></div></div></blockquote></div><br></div></div>