<html><head><style>
body {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        padding:1em;
        margin:auto;
        background:#fefefe;
}
h1, h2, h3, h4, h5, h6 {
        font-weight: bold;
}
h1 {
        color: #000000;
        font-size: 28pt;
}
h2 {
        border-bottom: 1px solid #CCCCCC;
        color: #000000;
        font-size: 24px;
}
h3 {
        font-size: 18px;
}
h4 {
        font-size: 16px;
}
h5 {
        font-size: 14px;
}
h6 {
        color: #777777;
        background-color: inherit;
        font-size: 14px;
}
hr {
        height: 0.2em;
        border: 0;
        color: #CCCCCC;
        background-color: #CCCCCC;
display: inherit;
}
p, blockquote, ul, ol, dl, li, table, pre {
        margin: 15px 0;
}
a, a:visited {
        color: #4183C4;
        background-color: inherit;
        text-decoration: none;
}
#message {
        border-radius: 6px;
        border: 1px solid #ccc;
        display:block;
        width:100%;
        height:60px;
        margin:6px 0px;
}
button, #ws {
        font-size: 12 pt;
        padding: 4px 6px;
        border-radius: 5px;
        border: 1px solid #bbb;
        background-color: #eee;
}
code, pre, #ws, #message {
        font-family: Monaco;
        font-size: 10pt;
        border-radius: 3px;
        background-color: #F8F8F8;
        color: inherit;
}
code {
        border: 1px solid #EAEAEA;
        margin: 0 2px;
        padding: 0 5px;
}
pre {
        border: 1px solid #CCCCCC;
        overflow: auto;
        padding: 4px 8px;
}
pre > code {
        border: 0;
        margin: 0;
        padding: 0;
}
#ws { background-color: #f8f8f8; }
.bloop_markdown table {
border-collapse: collapse;
font-family: Helvetica, arial, freesans, clean, sans-serif;
color: rgb(51, 51, 51);
font-size: 15px; line-height: 25px;
padding: 0; }
.bloop_markdown table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
.bloop_markdown table tr:nth-child(2n) {
background-color: #f8f8f8; }
.bloop_markdown table tr th {
font-weight: bold;
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }
.bloop_markdown table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }
.bloop_markdown table tr th :first-child, table tr td :first-child {
margin-top: 0; }
.bloop_markdown table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }
.bloop_markdown blockquote{
border-left: 4px solid #dddddd;
padding: 0 15px;
color: #777777; }
blockquote > :first-child {
margin-top: 0; }
blockquote > :last-child {
margin-bottom: 0; }
code, pre, #ws, #message {
word-break: normal;
word-wrap: normal;
}
hr {
display: inherit;
}
.bloop_markdown :first-child {
-webkit-margin-before: 0;
}
code, pre, #ws, #message {
font-family: Menlo, Consolas, Liberation Mono, Courier, monospace;
}
.send { color:#77bb77; }
.server { color:#7799bb; }
.error { color:#AA0000; }</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="bloop_markdown"><p>Hi Swift community,</p>
<p>I’d like you to think about the idea of being able to create protocols with a permutation path.</p>
<p>Recently I build a really tiny wrapper API around <code>NSLayoutAnchor</code>, where I wanted the user to have a nice and shiny API. The user can decide with which method he starts and optionally chain the other methods after that. The main restriction was that each method could only be used once, which is what a permutation offers. For that project I had to model and overload over 30 protocols, which overlaps only 5 different methods. If I had to add more methods, the permutation protocol model would silly explode.</p>
<p>You can look up a visual graph here: <a href="https://github.com/DevAndArtist/swift-functionallayout">https://github.com/DevAndArtist/swift-functionallayout</a></p>
<p>My pitch is purely additive and could be considered during phase 2!</p>
<p>Similar to <code>indirect</code> the new keyword would be applied to protocol members or to the protocol itself.</p>
<pre><code class="swift">protocol Foo {
permuting mutating func foo() -> Foo
permuting mutating func boo() -> Foo
permuting mutating func zoo() -> Foo
func bar() -> EscapingType
var x: Foo { get } // returns a new permutation path
}
permuting protocol Boo {
func a() -> Boo
func b() -> Boo
func c() -> EscapingType
var x: Boo { get } // participates in the current permutation chain
}
</code></pre>
<p>Example with <code>Foo</code>:</p>
<pre><code class="swift">class A : Foo {
permuting mutating func foo() -> Foo { return self }
permuting mutating func boo() -> Foo { return self }
func bar() -> EscapingType { return … }
var x: Foo { return self }
}
let a = A().foo()
a.
// From here only the following part of `Foo` would be visible
//
// func boo() -> Foo
// func zoo() -> Foo
// func bar() -> EscapingType
// var x: Foo { get }
//
// `foo` is not visible because it's already used in the current permutation chain
//
let aa = a.zoo()
//
// Visible API from `aa`
//
// func boo() -> Foo
// func bar() -> EscapingType
// var x: Foo { get }
//
aa.x.
//
// Since `x` is not marked with `permuting` keyword, it returns a new permutation chain where the whole `Foo` interface is again visible
//
aa.x.bar() // this will escape the permutation chain completely, because we're not returning `Foo` interface here
</code></pre>
<p>Only a chain of members that returning the same protocol (or even <code>Self</code>?) and are marked with the <code>permuting</code> keyword are considered as part of the same permutation. </p>
<p>Members that are not <code>permuting</code> will either escape the permutation chain or create a new one, like <code>bar</code> or <code>x</code> in the example above.</p>
<hr>
<p>Personally I think that would be a really handy tool for neat API design. It also helps to restrict some functional design while ease the build complexity. </p>
<p>My small wrapper API could be reduced to 3 protocols. </p>
<p></p></div><div class="bloop_original_html"><style>body{font-family:Helvetica,Arial;font-size:13px}</style><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div><br><div id="bloop_sign_1482742492944386048" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">-- <br>Adrian Zubarev<br>Sent with Airmail</div></div></div><div class="bloop_markdown"><p></p></div></body></html>