<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Daniel Duan's Articles About Foundation</title>
        <link>https://duan.ca/tag/foundation/</link>
        <atom:link href="https://duan.ca/tag/foundation/feed.xml" rel="self" type="application/rss+xml" />
            <item>
                <title>A Tale of Two Dates</title>
                <description>&#60;p&#62;Recently, I discovered a curious thing about &#60;code&#62;Date&#60;/code&#62;s in two large projects
I work on. Simply put, both projects receives, from various HTTP endpoints, the
same object component: a timestamp, and a duration. Combining these two pieces,
both projects derives two &#60;code&#62;Foundation.Date&#60;/code&#62;s to represent a time range. So far,
so good.&#60;/p&#62;
&#60;p&#62;However, project &#60;code&#62;A&#60;/code&#62; uses &#60;code&#62;Fonudation.DateInterval&#60;/code&#62; to represent this concept,
while project &#60;code&#62;B&#60;/code&#62; uses &#60;code&#62;Range&#38;lt;Date&#38;gt;&#60;/code&#62;. But why? Why represent the same component
differently? What a gigantic waste of brain power for everyone on both projects!&#60;/p&#62;
&#60;p&#62;So I set out to unify this thing. Wherever a &#60;code&#62;Range&#60;/code&#62; literal is used, I swap in
&#60;code&#62;DateInterval.init(start:end:)&#60;/code&#62;; &#60;code&#62;Range.lowerBound&#60;/code&#62; becomes
&#60;code&#62;DateInterval.start&#60;/code&#62;; &#60;code&#62;Range.upperBound&#60;/code&#62; becomes &#60;code&#62;DateInterval.end&#60;/code&#62;, etc. It
didn&#39;t take long to complete the conversion to &#60;code&#62;DateInterval&#60;/code&#62; in project &#60;code&#62;B&#60;/code&#62;,
now it builds and runs!&#60;/p&#62;
&#60;p&#62;Oh, wait, why are some tests failing in project &#60;code&#62;B&#60;/code&#62;? Shouldn&#39;t this just be an
mechanical change?&#60;/p&#62;
&#60;p&#62;I spent time investigating. The failing tests are for some very specific
business logic that I&#39;m not familiar with. So things took a while to become
clear. What felt like a long time later, I realized my mistake.&#60;/p&#62;
&#60;p&#62;(I&#39;m sorry if this has been obvious to you. You are a better Swift programmer!)&#60;/p&#62;
&#60;p&#62;Somewhere in project &#60;code&#62;B&#60;/code&#62; is the following:&#60;/p&#62;
&#60;pre&#62;&#60;code class=&#34;language-swift&#34;&#62;struct Item {
    let range: Range&#38;lt;Date&#38;gt;
}

struct Container {
    let items: [Item]
}

func containerFactory(range: Range&#38;lt;Date&#38;gt;, items: [Item]) -&#38;gt; Container {
    /// pretend there&#39;s more code here

    return Conatiner(items: items.filter { $0.range.contains(range.lowerBound) })
}
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;And of course, after my &#38;quot;refactor&#38;quot;, it became&#60;/p&#62;
&#60;pre&#62;&#60;code class=&#34;language-swift&#34;&#62;struct Item {
    let range: DateInterval
}

struct Container {
    let items: [Item]
}

func containerFactory(range: DateInterval, items: [Item]) -&#38;gt; Container {
    /// pretend there&#39;s more code here

    return Conatiner(items: items.filter { $0.range.contains(range.start) })
}
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Tests for &#60;code&#62;containerFactory&#60;/code&#62; failed. And here&#39;s why: &#60;strong&#62;&#60;code&#62;DateInterval.contains&#60;/code&#62;
is inclusive for its upper bound (&#60;code&#62;.end&#60;/code&#62;), whereas &#60;code&#62;Range.contains&#60;/code&#62; isn&#39;t!&#60;/strong&#62; You
can see it plainly by running the following&#60;/p&#62;
&#60;pre&#62;&#60;code class=&#34;language-swift&#34;&#62;import Foundation

let sooner = Date(timeIntervalSince1970: 0)
let later = sooner.addingTimeInterval(1000)

DateInterval(start: sooner, end: later).contains(later) // true
(sooner..&#38;lt;later).contains(later)                        // false
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;So here&#39;s what stumped me:&#60;/p&#62;
&#60;ol&#62;
&#60;li&#62;
&#60;p&#62;The 2 projects chose to interpret the same component differently, which
I didn&#39;t not expect.&#60;/p&#62;
&#60;/li&#62;
&#60;li&#62;
&#60;p&#62;I didn&#39;t know how &#60;code&#62;Foundation.DateInterval&#60;/code&#62; works.&#60;/p&#62;
&#60;/li&#62;
&#60;/ol&#62;
&#60;p&#62;Well, today I learned.&#60;/p&#62;
</description>
                <pubDate>Sat, 25 Aug 2018 17:11:43 -0700</pubDate>
                <link>https://duan.ca/2018/08/25/a-tale-of-two-dates/</link>
                <guid isPermaLink="true">https://duan.ca/2018/08/25/a-tale-of-two-dates/</guid>
            </item>
            <item>
                <title>Supporting Foundation.Data Without Depending On It</title>
                <description>&#60;p&#62;While implementing some file I/O APIs in &#60;a href=&#34;https://github.com/dduan/Pathos&#34;&#62;Pathos&#60;/a&#62;, I decided reading/writing
file content as &#60;code&#62;Foundation.Data&#60;/code&#62; is kind of important (can you blame me?). But
Pathos, by accident, does not depend on Swift &#60;code&#62;Foundation&#60;/code&#62;. Now what?&#60;/p&#62;
&#60;p&#62;After browsing the &#60;a href=&#34;https://developer.apple.com/documentation/foundation/data&#34;&#62;documentation&#60;/a&#62;, a pretty good solution emerged: &#60;code&#62;Data&#60;/code&#62; is
a sequence of bytes! Lets say we hand our users some bytes, they can easily
construct a &#60;code&#62;Data&#60;/code&#62; from it:&#60;/p&#62;
&#60;pre&#62;&#60;code class=&#34;language-swift&#34;&#62;let content: [UInt8] = try readBytes(fromPath &#38;quot;/tmp/test&#38;quot;)
Data(bytes: content)
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;Okay, so this built-in initializer makes &#60;code&#62;[UInt8]&#60;/code&#62; an acceptable substitute for
returning &#60;code&#62;Data&#60;/code&#62;. What can we do about about &#60;code&#62;Data&#60;/code&#62; as input? Well, turns out,
&#60;code&#62;Data&#60;/code&#62; is a &#60;code&#62;Collection&#60;/code&#62; of &#60;code&#62;UInt8&#60;/code&#62;s! So we can accept &#60;code&#62;Data&#60;/code&#62; indirectly like
so:&#60;/p&#62;
&#60;pre&#62;&#60;code class=&#34;language-swift&#34;&#62;func write&#38;lt;Bytes&#38;gt;(_ bytes: Bytes)
    where Bytes: Collection, Bytes.Element == UInt8
{
    // blah
}
&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;User can pass in a &#60;code&#62;Data&#60;/code&#62; as argument and it just works™.&#60;/p&#62;
&#60;p&#62;The only disadvantage of supporting &#60;code&#62;Data&#60;/code&#62; in these ways is that it requires
your user to discover it either via your excellent documentation, or through
their super good knowledge of &#60;code&#62;Foundation&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;&#60;em&#62;Update: this could also &#60;a href=&#34;https://mastodon.social/@helge/100573358160444340&#34;&#62;be&#60;/a&#62; &#60;a href=&#34;https://twitter.com/daniel_dunbar/status/1030938273047179264&#34;&#62;slower&#60;/a&#62; than using Data directly. Luckily
I&#39;m only doing file I/O here.&#60;/em&#62;&#60;/p&#62;
&#60;p&#62;But this is pretty nice, regardless.&#60;/p&#62;
</description>
                <pubDate>Sat, 18 Aug 2018 11:00:41 -0700</pubDate>
                <link>https://duan.ca/2018/08/18/supporting-data-without-depending-on-it/</link>
                <guid isPermaLink="true">https://duan.ca/2018/08/18/supporting-data-without-depending-on-it/</guid>
            </item>
            <item>
                <title>Contributing To Open-Source Swift</title>
                <description>&#60;p&#62;I discover, report, fix and merge a bug in the open-source Foundation project. And why, yes, on YouTube.&#60;/p&#62;
&#60;div class=&#34;video-container&#34;&#62;
    &#60;iframe src=&#34;https://www.youtube.com/embed/rwuj80W8TtI&#34; frameborder=&#34;0&#34; gesture=&#34;media&#34; allow=&#34;encrypted-media&#34; allowfullscreen&#62;&#60;/iframe&#62;
&#60;/div&#62;
&#60;ul&#62;
&#60;li&#62;Pull request: &#60;a href=&#34;https://github.com/apple/swift-corelibs-foundation/pull/1376&#34;&#62;https://github.com/apple/swift-corelibs-foundation/pull/1376&#60;/a&#62;&#60;/li&#62;
&#60;li&#62;SR-6647: &#60;a href=&#34;https://bugs.swift.org/browse/SR-6647&#34;&#62;https://bugs.swift.org/browse/SR-6647&#60;/a&#62;&#60;/li&#62;
&#60;/ul&#62;
</description>
                <pubDate>Sat, 23 Dec 2017 13:21:10 -0800</pubDate>
                <link>https://duan.ca/2017/12/23/contributing-to-open-source-foundation/</link>
                <guid isPermaLink="true">https://duan.ca/2017/12/23/contributing-to-open-source-foundation/</guid>
            </item>
    </channel>
</rss>