<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">Hi Kevin,</div><div class="gmail_quote"><br></div><div class="gmail_quote">Thank you for the proposal.  This is in line with the current design of String.  One of the Swift 3 goals is a redesign of String, to make the API easier to use.  I don&#39;t think that should block this improvement, since whatever the new design is, it should provide the UnicodeScalar view functionality for String, and the same API should be exposed on StaticString.</div><div class="gmail_quote"><br></div><div class="gmail_quote">On Sun, Dec 6, 2015 at 1:21 AM, Kevin Ballard via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><u></u>




<div><div>There&#39;s no way to create a substring of `StaticString` that&#39;s still typed as `StaticString`. This is occasionally desirable, for example if you want to extract the filename from `__FILE__` to pass to another API that requires a `StaticString`.<br></div>
<div> </div>
<div>I believe the best solution to this is to add a type `StaticString.UnicodeScalarView`, similar to `String.UnicodeScalarView`. `StaticString` would also be extended with a property `unicodeScalars` and two initializers to construct a `StaticString` from a `String.UnicodeScalarView`. The full proposed API looks like:<br></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">extension StaticString {</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  /// The value of `self` as a collection of [Unicode scalar values](<a href="http://www.unicode.org/glossary/#unicode_scalar_value" target="_blank">http://www.unicode.org/glossary/#unicode_scalar_value</a>).</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  public var unicodeScalars: UnicodeScalarView</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  /// Construct the `StaticString` corresponding to the given</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  /// `UnicodeScalarView`.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  public init(_: UnicodeScalarView)</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  /// Construct the `StaticString` corresponding to the given</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  /// `UnicodeScalarView` slice.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  public init(_: Slice&lt;UnicodeScalarView&gt;)</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  /// A collection of [Unicode scalar values](<a href="http://www.unicode.org/glossary/#unicode_scalar_value" target="_blank">http://www.unicode.org/glossary/#unicode_scalar_value</a>) that</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  /// encode a `StaticString`.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  public struct UnicodeScalarView : CollectionType {</span></div></div></blockquote><div><br></div><div>UnicodeScalarView should be a slice type, that is, UnicodeScalarView.SubSequence == UnicodeScalarView.</div><div><br></div><div>Then, you will be able to remove the StaticString.init(Slice&lt;UnicodeScalarView&gt;) initializer.</div><div><br></div><div>It should also be CustomStringConvertible, CustomDebugStringConvertible, with the same behavior as String.</div><div><br></div><div>Please also add a CustomReflectable conformance, that extracts the string value and reflects that.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    init(_: StaticString)</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    /// A position in a `StaticString.UnicodeScalarView`.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    public struct Index : BidirectionalIndexType, Comparable {</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      /// Returns the next consecutive value after `self`.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      ///</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      /// - Requires: The next value is representable.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      @warn_unused_result</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      public func successor() -&gt; Index</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      /// Returns the previous consecutive value before `self`.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      ///</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      /// - Requires: The previous value is representable.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      @warn_unused_result</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">      public func predecessor() -&gt; Index</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    }</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    /// The position of the first `UnicodeScalar` if the `StaticString` is</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    /// non-empty; identical to `endIndex` otherwise.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    public var startIndex: Index</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    /// The &quot;past the end&quot; position.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    ///</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    /// `endIndex` is not a valid argument to `subscript`, and is always</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    /// reachable from `startIndex` by zero or more applications of</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    /// `successor()`.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    public var endIndex: Index</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    /// Returns `true` iff `self` is empty.</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    public var isEmpty: Bool</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div> </div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">    public subscript(position: Index) -&gt; UnicodeScalar</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">  }</span><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif"><br></span></div>
<div><span style="font-family:menlo,consolas,&#39;courier new&#39;,monospace,sans-serif">}</span></div></div></blockquote><div><br></div><div>You omitted == and &lt; APIs for indices.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
<div>An alternative would be to make StaticString itself conform to CollectionType, but this is a bad idea for the same reasons that String doesn&#39;t conform to CollectionType.<br></div>
<div></div></div></blockquote></div><div class="gmail_extra"><br></div>Agreed.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Dmitri<br clear="all"><div><br></div>-- <br><div>main(i,j){for(i=2;;i++){for(j=2;j&lt;i;j++){if(!(i%j)){j=0;break;}}if<br>(j){printf(&quot;%d\n&quot;,i);}}} /*Dmitri Gribenko &lt;<a href="mailto:gribozavr@gmail.com" target="_blank">gribozavr@gmail.com</a>&gt;*/</div>
</div></div>