<html><body><div id="edo-message"><div><br><style>#edo-signature img {max-width: 90%}</style><div id="edo-signature" style="font-family: sans-serif, 'Helvetica Neue', Helvetica, Arial;font:'-apple-system-body';"></div></div></div><div id="edo-original">Responses inline<br><br><blockquote type="cite" style="margin:1ex 0 0 0;border-left:1px #ccc solid;padding-left:0.5ex;"><div>On May 7, 2017 at 15:16, &lt;<a href="mailto:andrew@projectdent.com">Andrew Hart</a>&gt; wrote:<br><br></div><div><div></div><div>



<style>
<![CDATA[
body{font-family:Helvetica,Arial;font-size:13px}
]]>
</style>
<title></title>



<div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
To respond to one of the main points I’ve seen, which is that this
isn’t necessary for arrays because the index you’re using is often
tied to data related to the array, such as in the example I gave
originally, where in `cellForRowAtIndexPath`, the index path is
probably informed by the length of the array.</div>
<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>
<div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
That’s true for data-backed code, but on iOS arrays are used in
other scenarios. I wanted to provide 3 additional examples where
optional arrays would be helpful that I’ve run across
recently:</div>
<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>
<div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px;color:rgba(0,0,0,1.0);margin:0px;line-height:auto">
1. When determining the video dimensions, frame rate or other
property of an AVAsset which you know is a video, you need to first
use assetTracks(withMediaType: String), which returns an array.
While I’m fairly sure that these video assets will all contain a
video track, it’s not a certainty, so to be safe I need to check
that one exists. Currently my code looks like this:</div>
<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>
<div id="bloop_customfont" style="margin:0px">
<div id="bloop_customfont" style="margin:0px">let videoTracks =
asset.tracks(withMediaType: AVMediaTypeVideo)</div>
<div id="bloop_customfont" style="margin:0px">if
videoTracks.count &gt; 0 {</div>
<div id="bloop_customfont" style="margin:0px">&nbsp; &nbsp; let videoTrack =
videoTracks[0]</div>
<div id="bloop_customfont" style="margin:0px">&nbsp; &nbsp; print("dimensions:
\(videoTrack.naturalSize)")</div>
<div id="bloop_customfont" style="margin:0px">}</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">With optional
arrays, this could be shortened to this:</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">if&nbsp;let
videoTrack = asset.tracks(withMediaType: AVMediaTypeVideo)[0]
{</div>
<div id="bloop_customfont" style="margin:0px">&nbsp; &nbsp; print("dimensions:
\(videoTrack.naturalSize)")</div>
<div id="bloop_customfont" style="margin:0px">}</div><div id="bloop_customfont" style="margin:0px"><br></div><div id="bloop_customfont" style="margin:0px"><br></div><div id="bloop_customfont" style="margin:0px"><b>In this case, where you want a nil if the Array is empty, try .first/.last</b></div><div id="bloop_customfont" style="margin:0px"><b><br></b></div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">2. UIVisualEffect
can display a blurred view on top of underlying views. If you wish
to add a tint color, it's simply added on top of the blur view's
own background color (by default, 0.97 white with 0.8 alpha) which
is provided by a subview. Your tint color being placed on top of
the blur view’s background color therefore degrades how that color
affects the content underneath, and also the overall opacity of the
content underneath. You might also not want the overlay to be as
strong as 0.8. To get around this, I might customise the
UIVisualEffectView to display my own base color displayed over the
blur. I know that the background color is set in the 2nd subview of
visualEffectView, so I’ll modify it like so:</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">
<div id="bloop_customfont" style="margin:0px">if
visualEffectView.subviews.count &gt;= 2 {</div><div id="bloop_customfont" style="margin:0px">&nbsp; &nbsp; let tintedView =
self.visualEffectView.subviews[1]</div>
<div id="bloop_customfont" style="margin:0px">&nbsp; &nbsp; tintedView.backgroundColor =
UIColor.red.withAlphaComponent(0.5)</div>
<div id="bloop_customfont" style="margin:0px">}</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">The checking for
the subviews count is important here - while it’s possible that iOS
may change the implementation of UIVisualEffectViews in future, and
break my UI, I would much prefer that over the app crashing.</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">With optional
arrays, this UI code could be shortened to this:</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">
visualEffectView.subviews[1]?.backgroundColor =
UIColor.red.withAlphaComponent(0.5)</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">Obviously this kind
of manipulation is hacky and isn’t encouraged, but it’s an example
of some of the more finicky UI work that in reality is often
required on iOS in order to achieve certain goals.</div>
<div id="bloop_customfont" style="margin:0px"><br></div><div id="bloop_customfont" style="margin:0px"><br></div><div id="bloop_customfont" style="margin:0px"><b>I would refer you to my previous email, specifically point #2: you have some external knowledge about what to expect in "subviews" at the second position. In this case, I would really expect you to be commenting why you are getting the subview at index 1, rather than .first, .last, or any other arbitrary subview. As you say, Apple could break your App by simply adding another private view. If you're doing these kind of hacks, and sometimes they are necessary, you should be wrapping them behind conditions which test as many assumptions as possible (e.g. What exactly do you expect at subviews[1]? What about subviews[2]? Is there any way to rewrite your code so that you derive the index by inspecting the view hierarchy at runtime instead of hard-coding exactly how it should look?)</b></div><div id="bloop_customfont" style="margin:0px"><b><br></b></div><div id="bloop_customfont" style="margin:0px"><b>Eventually, you may get to the point where it's no longer a hack, but actually a very clever, &nbsp;resilient use of documented guarantees. That's where we'd all like to be.</b></div><div id="bloop_customfont" style="margin:0px"><b><br></b></div>
<div id="bloop_customfont" style="margin:0px">3. I also think
optional arrays can be used for clarity of purpose, in the same way
that dictionary keys are. In a different scenario, such as when
attempting to extract data from a string, this is how code might
currently look:</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">
<div id="bloop_customfont" style="margin:0px">let components =
coordinatesString.components(separatedBy: ",")</div>
<div id="bloop_customfont" style="margin:0px">&nbsp; &nbsp;
&nbsp; &nbsp;&nbsp;</div>
<div id="bloop_customfont" style="margin:0px">if components.count &lt; 2 {</div>
<div id="bloop_customfont" style="margin:0px">&nbsp; &nbsp; return nil</div>
<div id="bloop_customfont" style="margin:0px">}</div>
<div id="bloop_customfont" style="margin:0px">&nbsp; &nbsp;
&nbsp; &nbsp;&nbsp;</div>
<div id="bloop_customfont" style="margin:0px">let latitudeString = components[0]</div>
<div id="bloop_customfont" style="margin:0px">let longitudeString = components[1]</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">Notice that in
advance you’re saying “ok, so I know there’ll be 2 components I
require later on, so I’ll check to make sure I have at least 2
components, and then after that I’ll explain what those are for”.
Instead, it could look like this:</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">let components =
coordinatesString.components(separatedBy: ",”)</div>
<div id="bloop_customfont" style="margin:0px"></div>
<div id="bloop_customfont" style="margin:0px">let latitudeString
= components[0]</div>let longitudeString =
components[1]</div>
<div id="bloop_customfont" style="margin:0px"><br>
<div id="bloop_customfont" style="margin:0px">if latitudeString
== nil || longitudeString == nil {</div>
<div id="bloop_customfont" style="margin:0px">&nbsp; &nbsp; return nil</div>
<div id="bloop_customfont" style="margin:0px">}</div>
<div id="bloop_customfont" style="margin:0px"><br></div>
<div id="bloop_customfont" style="margin:0px">The intent is much
clearer here. You want to extract latitude and longitude, but if
either of those don’t exist then return nil.</div><div id="bloop_customfont" style="margin:0px"><br></div><div id="bloop_customfont" style="margin:0px"><b>I don't see how the latter example is significantly better than the first. It doesn't reduce code size or improve legibility, and I fear any general thing we might try to add would be overused and ultimately degrade the standard library. If you find Array bounds checking too onerous, you can wrap it to build your own type or extend it to provide convenient shorthands. I can understand why you might want to add these things sometimes,&nbsp;<span style="-webkit-text-size-adjust: auto; background-color: rgba(255, 255, 255, 0);">but in general I think it's not a good change for the standard library.</span></b></div></div></div></div></div></div></blockquote><blockquote type="cite" style="margin:1ex 0 0 0;border-left:1px #ccc solid;padding-left:0.5ex;"><div>
<div id="bloop_sign_1494153577747917056" class="bloop_sign"></div>
<br>
<p class="airmail_on">On 17 April 2017 at 20:22:10, Riley Testut
(<a href="mailto:rileytestut@gmail.com">rileytestut@gmail.com</a>)
wrote:</p>
<blockquote type="cite" class="clean_bq">
<div style="word-wrap:break-word" class="">
<div>
<div class="">
<blockquote type="cite" class="">
<div class="" style="word-wrap:break-word">
<span>Dynamic programming comes to mind.</span></div>
</blockquote>
</div>
<div class=""><span><br class=""></span></div>
<div class=""><span>Wouldn’t you then be able to use
Array(repeating:count:) and repeat 0 (or something else) to achieve
this then?</span></div>
<div class=""><span><br class=""></span></div>
<div class=""><span>Yes, less performant than alloc’ing array
(since we need to fill in default values), but doing otherwise
would go against Swift’s safety model. If you truly wanted that
behavior, you can use the UnsafePointer methods anyway
(AFAIK).</span></div>
<span><br class=""></span>
<div>
<blockquote type="cite" class="">
<div class=""><span>On Apr 16, 2017, at 9:18 PM, Saagar Jha
&lt;<a href="mailto:saagar@saagarjha.com" class="">saagar@saagarjha.com</a>&gt; wrote:</span></div>
<span><br class="Apple-interchange-newline"></span>
<div class="">
<div style="word-wrap:break-word" class=""><span>Dynamic programming comes to mind.</span>
<div class=""><span><br class=""></span>
<div class="">
<div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word" class=""><span>Saagar Jha</span></div>
</div>
<span><br class=""></span>
<div class="">
<blockquote type="cite" class="">
<div class=""><span>On Apr 16, 2017, at 19:33, Riley Testut
&lt;<a href="mailto:rileytestut@gmail.com" class="">rileytestut@gmail.com</a>&gt; wrote:</span></div>
<span><br class="Apple-interchange-newline"></span>
<div class="">
<div dir="auto" class="">
<div class=""></div>
<div class=""><span>My bad, should have phrased my response better
:^)</span></div>
<div class=""><span><br class=""></span></div>
<div class=""><span>Under what circumstances would you need to be
able to assign elements in an array out of order, while also
requiring Array size/performance? (Genuinely curious, not trying to
attack).</span></div>
<div class=""><span><br class=""></span></div>
<div class=""><span>IMO, if the differences between Array and
Dictionary would cause that much of an issue for your
implementation, my guess is you have more important priorities than
the need to assign elements out-of-order 😉 I don't think we'd need
to add another type to the standard library for this use
case.</span></div>
<div class=""><span><br class="">
On Apr 16, 2017, at 11:22 AM, Saagar Jha &lt;<a href="mailto:saagar@saagarjha.com" class="">saagar@saagarjha.com</a>&gt;
wrote:<br class="">
<br class=""></span></div>
<blockquote type="cite" class="">
<div class=""><span>A Dictionary uses a lot more space than an
Array, though, and allow for bogus keys like “-1”, etc.</span>
<div class=""><span><br class=""></span>
<div class="">
<div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word" class=""><span>Saagar Jha</span></div>
</div>
<span><br class=""></span>
<div class="">
<blockquote type="cite" class="">
<div class=""><span>On Apr 16, 2017, at 10:34, Riley Testut via
swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</span></div>
<span><br class="Apple-interchange-newline"></span>
<div class="">
<div dir="auto" class="">
<div class=""></div>
<div class="">
<blockquote type="cite" class=""><span><font class=""><span style="background-color:rgba(255,255,255,0)" class="">Personally,
the only valid use-case I can think of is when you want to
initialise an Array’s elements out-of-order - i.e., you want to set
a value for myArray[2] despite myArray[0] and [1] not being
populated. In that case, it would be better to have some kind of
SparseArray type, and for us to have a proper API for unsafe
initialisation of stdlib
types.&nbsp;</span></font></span></blockquote>
<br class=""></div>
<div class="">Wouldn't the same functionality be accomplished by a
Dictionary with Int as the key type?</div>
<div class=""><br class="">
On Apr 14, 2017, at 10:00 AM, Karl Wagner via swift-evolution
&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
<br class=""></div>
<blockquote type="cite" class="">
<div class="">
<blockquote type="cite" class=""><span class="">I'd actually say
the #1 reason not to add this feature is that a lot of developers
don't seem to understand this, and they're likely to use the
feature to make their code try to continue in the face of
programmer error instead of trapping like it properly should. A
program in an inconsistent state is dangerous; best to stop it
quickly before it does some damage.)</span><br class=""></blockquote>
<br class="">
<span class="">Right, so I think the reason is actually that a lot
of developers don’t understand what an Array is. There are two
use-cases for an Array:</span><br class="">
<br class="">
<span class="">1) As a string of items, don’t care about the
length. The maximum prior knowledge you can have is that the order
may or may not be significant. This includes operations like
iteration, mapping, reducing and filtering.</span><br class="">
<span class="">2) As a string of items of specific length. You have
prior knowledge about what you expect to find at each location.
This includes operations like random-access subscripting, which is
what we’re talking about.</span><br class="">
<br class="">
<span class="">Basically, the interesting part of a statement such
as “let someValue = myArray[2]” is: why index 2? What’s so special
about that element; why couldn't someValue be the item at any index
N instead? It’s because we know to expect something of special
significance at index 2.</span><br class="">
<br class="">
<span class="">In that case, the only time myArray[2] will fail is
when your prior knowledge breaks down. The type-system has no way
to encode and check for the length of an Array, and that has
allowed somebody to pass in a bad value. So what to
do?</span><br class="">
<br class="">
<span class="">A) If you absolutely require a value for myArray[2]:
Insert a precondition check.</span><br class="">
<span class="">B) If you can still continue without myArray[2]:
Check the length of the Array. Your logic will be branching anyway
in this case, to account for the value (and subsequent values)
being/not being present.</span><br class="">
<br class="">
<br class="">
<span class="">Personally, the only valid use-case I can think of
is when you want to initialise an Array’s elements out-of-order -
i.e., you want to set a value for myArray[2] despite myArray[0] and
[1] not being populated. In that case, it would be better to have
some kind of SparseArray type, and for us to have a proper API for
unsafe initialisation of stdlib types.</span><br class="">
<br class="">
<span class="">- Karl</span><br class="">
<span class="">_______________________________________________</span><br class="">
<span class="">swift-evolution mailing list</span><br class="">
<span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class="">
<span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class="">
</div>
</blockquote>
</div>
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</div>
</blockquote>
</div>
<br class=""></div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
<br class=""></div>
</div>
</div>
</blockquote>
</div>
<br class=""></div>
</div>
</blockquote>


</div>
</blockquote></div></body></html>