https://ApolloZhu.github.io/enAZ2023-04-17T12:42:46.000Zhttps://apollozhu.github.io/en/2023/04/17/backporting-swiftui-apis-with-result-builders/Backporting SwiftUI APIs with Result Builders<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><p>When Apple announced SwiftUI back in 2019, there’s a new language feature called “function builder” that didn’t go through the Swift Evolution process but was shipped with Apple’s Swift toolchain to make SwiftUI a reality. I’m glad that the community decided to adopt this feature as result builders, allowing us to mimic SwiftUI’s API ourselves.</p>
<span id="more"></span>
<div class="note danger"><h2 id="disclaimer"><a class="markdownIt-Anchor" href="#disclaimer"></a> Disclaimer</h2>
<p>This code is written without knowledge of how Apple’s SwiftUI framework actually works.</p>
</div>
<h2 id="motivation"><a class="markdownIt-Anchor" href="#motivation"></a> Motivation</h2>
<p>When <a href="https://invent.kde.org/network/kdeconnect-ios">KDE Connect iOS</a> tried to lower deployment target to iOS 14, we ran into the limitation of <a href="https://sarunw.com/posts/how-to-show-multiple-alerts-on-the-same-view-in-swiftui/">not being able to show multiple alerts in the same View</a>, and had to find a very hacky <a href="https://invent.kde.org/network/kdeconnect-ios/-/merge_requests/16">workaround</a> for iOS 14 only by adding many hidden views to the view hierarchy, and duplicating the buttons/texts:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> <span class="keyword">#available</span>(<span class="keyword">iOS</span> <span class="number">15.0</span>, <span class="operator">*</span>) {</span><br><span class="line"> content</span><br><span class="line"> .alert(title1, isPresented: <span class="variable">$isPresented1</span>) {</span><br><span class="line"> primaryButton1</span><br><span class="line"> secondaryButton1</span><br><span class="line"> } message: {</span><br><span class="line"> subtitle1</span><br><span class="line"> }</span><br><span class="line"> .alert(<span class="operator">...</span>)</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> content</span><br><span class="line"></span><br><span class="line"> hiddenView1</span><br><span class="line"> .alert(<span class="variable">$isPresented1</span>) {</span><br><span class="line"> <span class="type">Alert</span>(</span><br><span class="line"> title: title1,</span><br><span class="line"> message: subtitle1,</span><br><span class="line"> primaryButton: primaryButton1,</span><br><span class="line"> secondaryButton: secondaryButton1</span><br><span class="line"> )</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> hiddenView2</span><br><span class="line"> .alert(<span class="operator">...</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="proposed-solution"><a class="markdownIt-Anchor" href="#proposed-solution"></a> Proposed Solution</h2>
<p>By mimicking SwiftUI’s new <code>alert</code> API but making it available on iOS 14, we could hide the complexity away from the call site allowing only writing code as in the iOS 15 branch, while doing all the dirty work inside the actual implementation:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">extension</span> <span class="title class_">View</span> {</span><br><span class="line"> <span class="keyword">func</span> <span class="title function_">alert</span>(</span><br><span class="line"> <span class="keyword">_</span> <span class="params">titleKey</span>: <span class="type">LocalizedStringKey</span>,</span><br><span class="line"> <span class="params">isPresented</span>: <span class="type">Binding</span><<span class="type">Bool</span>>,</span><br><span class="line"> <span class="meta">@AlertActionBuilder</span> <span class="params">actions</span>: () -> <span class="type">AlertActionBuilder</span>.<span class="type">Buttons</span>?,</span><br><span class="line"> <span class="meta">@ViewBuilder</span> <span class="params">message</span>: () -> <span class="type">Text</span>?</span><br><span class="line"> ) -> <span class="keyword">some</span> <span class="type">View</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>But wait, what is <code>AlertActionBuilder</code>? To understand why we need to introduce this new thingy, let’s first look at what’s <code>ViewBuilder</code>, and why we can’t use <code>ViewBuilder</code> for our purpose.</p>
<h2 id="detailed-design"><a class="markdownIt-Anchor" href="#detailed-design"></a> Detailed Design</h2>
<h3 id="viewbuilder"><a class="markdownIt-Anchor" href="#viewbuilder"></a> <code>ViewBuilder</code></h3>
<p>The new iOS 15 SwiftUI alert API is defined as follows:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">extension</span> <span class="title class_">View</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">func</span> <span class="title function_">alert</span><<span class="type">A</span>, <span class="type">M</span>>(</span><br><span class="line"> <span class="keyword">_</span> <span class="params">titleKey</span>: <span class="type">LocalizedStringKey</span>,</span><br><span class="line"> <span class="params">isPresented</span>: <span class="type">Binding</span><<span class="type">Bool</span>>,</span><br><span class="line"> <span class="meta">@ViewBuilder</span> <span class="params">actions</span>: () -> <span class="type">A</span>,</span><br><span class="line"> <span class="meta">@ViewBuilder</span> <span class="params">message</span>: () -> <span class="type">M</span></span><br><span class="line"> ) -> <span class="keyword">some</span> <span class="type">View</span> <span class="keyword">where</span> <span class="type">A</span> : <span class="type">View</span>, <span class="type">M</span> : <span class="type">View</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Note the <code>@ViewBuilder</code> attribute in front of <code>actions</code> and <code>message</code>: this is what enables us to write code like:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> body: <span class="keyword">some</span> <span class="type">View</span> {</span><br><span class="line"> <span class="type">Button</span>(<span class="operator">...</span>)</span><br><span class="line"> <span class="type">Button</span>(<span class="operator">...</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Normally, when the Swift compilers sees values that are not used as part of another expression, assigned to a variable, or returned, it will complain about “Result of … is unused,” as you can see by writing the same code but for a computed property that’s not a <code>View</code>'s <a href="https://developer.apple.com/documentation/swiftui/view/body-swift.property"><code>body</code></a>:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> buttons: <span class="keyword">some</span> <span class="type">View</span> { <span class="comment">// Function declares an opaque return type,</span></span><br><span class="line"> <span class="comment">// but has no return statements in its body</span></span><br><span class="line"> <span class="comment">// from which to infer an underlying type</span></span><br><span class="line"> <span class="type">Button</span>(<span class="operator">...</span>) <span class="comment">// Result of 'Button<Label>' initializer is unused</span></span><br><span class="line"> <span class="type">Button</span>(<span class="operator">...</span>) <span class="comment">// Did you mean to return the last expression?</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>However, by annotating it with SwiftUI’s custom <code>ViewBuilder</code> attribute, the code now compiles by building a combined result after getting transformed using <a href="https://developer.apple.com/documentation/swiftui/viewbuilder#building-content">rules specified by <code>ViewBuilder</code></a>, which the final result made using its <code>buildBlock</code> function is then <a href="https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties/#Shorthand-Getter-Declaration">implicitly returned</a>:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ViewBuilder</span></span><br><span class="line"><span class="keyword">var</span> buttons: <span class="keyword">some</span> <span class="type">View</span> {</span><br><span class="line"> <span class="comment">/* let v1 = */</span> <span class="type">Button</span>(<span class="operator">...</span>)</span><br><span class="line"> <span class="comment">/* let v2 = */</span> <span class="type">Button</span>(<span class="operator">...</span>)</span><br><span class="line"> <span class="comment">// return buildBlock(v1, v2)</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Because code annotated with the <code>ViewBuilder</code> attribute doesn’t follow how Swift code normally gets compiled, it’s kind of like a miniature language within Swift specialized for constructing views from closures (i.e. things within braces). We call this kind of language a <strong>Domain Specific Language</strong>, or <strong>DSL</strong>.</p>
<h3 id="differences-between-ios-14-and-ios-15-api"><a class="markdownIt-Anchor" href="#differences-between-ios-14-and-ios-15-api"></a> Differences Between iOS 14 and iOS 15 API</h3>
<p>While the iOS 15 API allows arbitrary views as the list of <code>actions</code>, the iOS 14 API requires either</p>
<ol>
<li>no buttons,</li>
<li>a single dismiss button, or</li>
<li>a primary and a secondary button.</li>
</ol>
<p>This is fine as <code>ViewBuilder</code>'s <code>buildBlock</code> function returns a <code>TupleView</code>, from which we can extract the buttons to pass to iOS 14’s API. However, the bigger problem is that <code>ButtonRole</code> is only available on iOS 15 and we can’t peek inside SwiftUI’s <code>Button</code> <code>struct</code> to figure out what role it has – nor can we do so on iOS 14 where the <code>ButtonRole</code> type doesn’t exist. Thus, we’ll need our own type to store relevant information then later convert it to <code>Button</code> on iOS 15 and <code>Alert.Button</code> on iOS 14:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">_Button</span> {</span><br><span class="line"> <span class="keyword">enum</span> <span class="title class_">Role</span> {</span><br><span class="line"> <span class="keyword">case</span> cancel, destructive</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">let</span> titleKey: <span class="type">LocalizedStringKey</span></span><br><span class="line"> <span class="keyword">let</span> role: <span class="type">Role</span>?</span><br><span class="line"> <span class="keyword">let</span> action: () -> <span class="type">Void</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">@available</span>(<span class="keyword">iOS</span>, introduced: <span class="number">15</span>)</span><br><span class="line"> <span class="keyword">var</span> iOS15Button: <span class="keyword">some</span> <span class="type">View</span> { <span class="operator">...</span> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">@available</span>(<span class="keyword">iOS</span>, deprecated: <span class="number">15</span>)</span><br><span class="line"> <span class="keyword">var</span> iOS14Button: <span class="type">Alert</span>.<span class="type">Button</span> { <span class="operator">...</span> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="making-alertactionbuilder-a-dsl-for-building-alert-actions"><a class="markdownIt-Anchor" href="#making-alertactionbuilder-a-dsl-for-building-alert-actions"></a> Making <code>AlertActionBuilder</code> - a DSL for Building Alert Actions</h3>
<p>Making a DSL in Swift using result builder is very simple: declaring a new type and annotate it with the <code>resultBuilder</code> attribute, then provide at least one static <code>buildBlock</code>/<code>buildPartialBlock</code> method:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">@resultBuilder</span></span><br><span class="line"><span class="keyword">enum</span> <span class="title class_">AlertActionBuilder</span> {</span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">func</span> <span class="title function_">buildBlock</span>(<span class="comment">/* TODO */</span>) -> <span class="comment">/* TODO */</span> { <span class="operator">...</span> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>To allow building the 3 types of alert buttons mentioned above, we can represent the result as an <code>Optional<AlertActionBuilder.Buttons></code>:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">extension</span> <span class="title class_">AlertActionBuilder</span> {</span><br><span class="line"> <span class="keyword">enum</span> <span class="title class_">Buttons</span> {</span><br><span class="line"> <span class="keyword">case</span> dismiss(_Button)</span><br><span class="line"> <span class="keyword">case</span> primary(_Button, secondary: _Button)</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// AlertActionBuilder.Buttons? has an additional case</span></span><br><span class="line"> <span class="comment">// `nil` to represent no buttons.</span></span><br></pre></td></tr></table></figure>
<p>The Swift compiler will try to match contents inside an <code>@AlertActionBuilder</code> closure with the <code>buildBlock</code> functions defined. For example, if there’s nothing inside the curly braces, it will choose:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> <span class="keyword">func</span> <span class="title function_">buildBlock</span>() -> <span class="type">Buttons</span>? {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Similarly, it will do so for the one button and two buttons cases:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"> <span class="keyword">static</span> <span class="keyword">func</span> <span class="title function_">buildBlock</span>(<span class="keyword">_</span> <span class="params">button</span>: _Button) -> <span class="type">Buttons</span>? {</span><br><span class="line"> <span class="keyword">return</span> .dismiss(button)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">func</span> <span class="title function_">buildBlock</span>(<span class="keyword">_</span> <span class="params">button1</span>: _Button, <span class="keyword">_</span> <span class="params">button2</span>: _Button) -> <span class="type">Buttons</span>? {</span><br><span class="line"> <span class="comment">// Maybe switch the order depending what roles each of these buttons has</span></span><br><span class="line"> <span class="keyword">return</span> .primary(button1, secondary: button2)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>That’s it! We can now write code like:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">content</span><br><span class="line"> .alert(title, isPresented: <span class="variable">$isPresented</span>) {</span><br><span class="line"> _Button(<span class="string">"Unpair"</span>, role: .destructive) { <span class="operator">...</span> }</span><br><span class="line"></span><br><span class="line"> _Button(<span class="string">"Cancel"</span>, role: .dismiss) { <span class="operator">...</span> }</span><br><span class="line"> }</span><br><span class="line"> .alert(<span class="operator">...</span>)</span><br></pre></td></tr></table></figure>
<p>and switch on <code>AlertActionBuilder.Buttons?</code> inside our <code>alert</code> API implementation to call appropriate SwiftUI APIs on both iOS 14 and iOS 15. The need to use <code>_Button</code> instead of <code>Button</code> is annoying though, so let’s use the tricked mentioned in <a href="/en/2023/04/13/shimming-swiftui-apis-by-hacking-overload-resolution/" title="Shimming SwiftUI APIs by Hacking Overload Resolution">Shimming SwiftUI APIs by Hacking Overload Resolution</a> to fix that:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">func</span> <span class="title function_">Button</span>(</span><br><span class="line"> <span class="keyword">_</span> <span class="params">titleKey</span>: <span class="type">LocalizedStringKey</span>,</span><br><span class="line"> <span class="params">role</span>: _Button.<span class="type">Role</span>? <span class="operator">=</span> <span class="literal">nil</span>,</span><br><span class="line"> <span class="params">action</span>: <span class="keyword">@escaping</span> () -> <span class="type">Void</span></span><br><span class="line">) -> _Button {</span><br><span class="line"> _Button(titleKey, role: role, action: action)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Way to go!</p>
<h2 id="further-readings"><a class="markdownIt-Anchor" href="#further-readings"></a> Further Readings</h2>
<p>The full implementation can be found at <a href="https://invent.kde.org/network/kdeconnect-ios/-/merge_requests/34">[Refactor] Reduce code duplication for iOS 14 support</a>. To learn more about building DSLs and using result builders, you can checkout:</p>
<ul>
<li><a href="https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md">SE-0289: Result builders</a></li>
<li><a href="https://github.com/apple/swift-evolution/blob/main/proposals/0348-buildpartialblock.md">SE-0348: <code>buildPartialBlock</code> for result builders</a></li>
<li><a href="https://developer.apple.com/videos/play/wwdc2021/10253/">WWDC21-10253: Write a DSL in Swift using result builders</a></li>
<li><a href="https://forums.swift.org/t/improved-result-builder-implementation-in-swift-5-8/63192">Improved Result Builder Implementation in Swift 5.8</a></li>
<li><a href="https://github.com/ApolloZhu/BoolBuilder"><code>ApolloZhu/BoolBuilder</code>: <code>@resultBuilder</code> for building a <code>Bool</code></a></li>
</ul>
<p>On a side note, I’m not sure what <a href="https://github.com/apple/swift-evolution/blob/main/visions/macros.md">macros</a> – which is different from result builders and <a href="https://github.com/apple/swift-evolution/blob/main/proposals/0258-property-wrappers.md">property wrappers</a> though all of them begin with an <code>@</code> – will impact how people approach implementing DSLs in Swift in the future, but they are certainly interesting for library authors to explore as well.</p>
2023-04-17T12:42:46.000Zhttps://apollozhu.github.io/en/2023/04/13/shimming-swiftui-apis-by-hacking-overload-resolution/Shimming SwiftUI APIs by Hacking Overload Resolution<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><p>The best way to build an app is with Swift and SwiftUI – if you don’t have to support older iOS versions. But it doesn’t have to be like this – with one weird little trick.</p>
<span id="more"></span>
<h2 id="motivation"><a class="markdownIt-Anchor" href="#motivation"></a> Motivation</h2>
<p>Because Swift doesn’t support back deploying types and only recently implemented <a href="https://github.com/apple/swift-evolution/blob/main/proposals/0376-function-back-deployment.md">SE-0376 Function Back Deployment</a>, SwiftUI as a system framework can only introduce new features for the latest iOS version. As <a href="https://invent.kde.org/network/kdeconnect-ios">KDE Connect iOS</a> needs to support iOS 14, if we want to use some of the newer SwiftUI APIs, we have to check what’s the iOS version of the current device, then execute different branches of code depending on what API is available:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> <span class="keyword">#available</span>(<span class="keyword">iOS</span> <span class="number">15</span>, <span class="operator">*</span>) {</span><br><span class="line"> theSameActualViewContent</span><br><span class="line"> .alert(title, isPresented: <span class="variable">$isPresented</span>) {</span><br><span class="line"> primaryButton</span><br><span class="line"> secondaryButton</span><br><span class="line"> } message: {</span><br><span class="line"> subtitle</span><br><span class="line"> }</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> theSameActualViewContent</span><br><span class="line"> .alert(isPresented: isPresented) {</span><br><span class="line"> <span class="type">Alert</span>(</span><br><span class="line"> title: title,</span><br><span class="line"> message: subtitle,</span><br><span class="line"> primaryButton: primaryButton,</span><br><span class="line"> secondaryButton: secondaryButton</span><br><span class="line"> )</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Not only do we have to add the <code>if #available</code> checks, to reduce code duplication, we need to introduce variables like <code>theSameActualViewContent</code>, <code>title</code>, and <code>primaryButton</code>. If we have multiple alerts, we have to repeat this process for every single one of them. The friction makes writing SwiftUI not fun anymore.</p>
<h2 id="proposed-solution"><a class="markdownIt-Anchor" href="#proposed-solution"></a> Proposed Solution</h2>
<p>One way to solve this is to “bring the new APIs to an older environment, using only the means of that environment,” or implement what people call a “<strong>shim</strong>.”</p>
<div class="note info"><p>Other common terms that describes this are “backport” and “polyfill.”</p>
</div>
<p>While libraries like <a href="https://github.com/shaps80/SwiftUIBackports">SwiftUI Backports</a> exists, there are still times that we need to do this ourselves if the library hasn’t gotten to the thing we want, such as support for <code>@FocusState</code> on iOS 14. In addition, to make it easier to later drop support for older iOS versions, it’s possible – and the easiest – for in house wrapper/implementation to utilize <strong>overload resolution</strong> to keep the shim API exactly the same as SwiftUI at call sites. This means, instead of needing to add some disambiguator like in <a href="https://davedelong.com/blog/2021/10/09/simplifying-backwards-compatibility-in-swift/">this blog post</a>:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Backport</span>.<span class="type">FocusState</span> <span class="keyword">var</span> isFocused</span><br><span class="line"><span class="operator">...</span></span><br><span class="line">view.backport.refreshable { <span class="operator">...</span> }</span><br></pre></td></tr></table></figure>
<p>or using a different name such as in <a href="https://www.youtube.com/watch?v=2IB4CuSRea4">this YouTube video</a> and many other online tutorials:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@MyFocusState</span> <span class="keyword">var</span> isFocused</span><br><span class="line"><span class="operator">...</span></span><br><span class="line">view.myRefreshable { <span class="operator">...</span> }</span><br></pre></td></tr></table></figure>
<p>the goal is to directly write:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@FocusState</span> <span class="keyword">var</span> isFocused</span><br><span class="line"><span class="operator">...</span></span><br><span class="line">view.refreshable { <span class="operator">...</span> }</span><br></pre></td></tr></table></figure>
<p>as if the shim doesn’t exist.</p>
<h2 id="overload-resolution"><a class="markdownIt-Anchor" href="#overload-resolution"></a> Overload Resolution</h2>
<p>When multiple types, functions, and/or variables from different modules share the same name <code>X</code>, the compiler needs to figure out which one exactly are you referring to when you write <code>X</code> in source code. According to Swift’s documentation on <a href="https://github.com/apple/swift/blob/main/docs/Modules.rst#ambiguity">resolving name lookup ambiguities</a>:</p>
<blockquote>
<ol>
<li>Declarations in the current source file are best.</li>
<li>Declarations from other files in the same module are better than declarations from imports.</li>
<li>Declarations from selective imports are better than declarations from non-selective imports. (This may be used to give priority to a particular module for a given name.)</li>
<li>Every source file implicitly imports the core standard library as a non-selective import.</li>
<li>If the name refers to a function, normal overload resolution may resolve ambiguities.</li>
</ol>
</blockquote>
<p>That means we could provide shims by declaring, for example:</p>
<ol>
<li>a type alias called <code>FocusState</code> to shadow SwiftUI’s definition of <code>FocusState</code> type</li>
</ol>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typealias</span> <span class="type">FocusState</span> <span class="operator">=</span> <span class="type">State</span></span><br></pre></td></tr></table></figure>
<ol start="2">
<li>an “overload” global function that’s similar to SwiftUI’s definition of <code>Button.init</code> initializer but with custom types available on iOS 14</li>
</ol>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">func</span> <span class="title function_">Button</span>(</span><br><span class="line"> <span class="keyword">_</span> <span class="params">titleKey</span>: <span class="type">LocalizedStringKey</span>,</span><br><span class="line"> <span class="params">role</span>: _Button.<span class="type">Role</span>? <span class="operator">=</span> <span class="literal">nil</span>,</span><br><span class="line"> <span class="params">action</span>: <span class="keyword">@escaping</span> () -> <span class="type">Void</span></span><br><span class="line">) -> _Button {</span><br><span class="line"> <span class="operator">...</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ol start="3">
<li>an overload function called <code>refreshable</code> with a slightly different signature but indistinguishable from call site if using trailing closures</li>
</ol>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">extension</span> <span class="title class_">View</span> {</span><br><span class="line"> <span class="comment">// This has signature refreshable(_:) while the SwiftUI one is refreshable(action:)</span></span><br><span class="line"> <span class="keyword">func</span> <span class="title function_">refreshable</span>(<span class="keyword">_</span> <span class="params">action</span>: <span class="keyword">@escaping</span> <span class="meta">@Sendable</span> () <span class="keyword">async</span> -> <span class="type">Void</span>) -> <span class="keyword">some</span> <span class="type">View</span> {</span><br><span class="line"> <span class="operator">...</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Since these are “Declarations from other files in the same module,” they are “better” than declarations imported from the SwiftUI framework. As they are available on iOS 14, the compiler will happy take these shims over the actual SwiftUI APIs.</p>
<h2 id="migration"><a class="markdownIt-Anchor" href="#migration"></a> Migration</h2>
<p>What needs to happen when we drop support for iOS 14? Just delete the files implementing the shims. To make sure we remember doing this, we can mark the shim APIs to be obsolete by the iOS version they become available at:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">@available</span>(<span class="keyword">iOS</span>, obsoleted: <span class="number">15</span>,</span><br><span class="line"> message: <span class="string">"Delete this file and use SwiftUI.FocusState instead."</span>)</span><br><span class="line"><span class="keyword">typealias</span> <span class="type">FocusState</span> <span class="operator">=</span> <span class="type">State</span></span><br></pre></td></tr></table></figure>
<p>Since the backport implementation is different from SwiftUI, always test the app to make sure other parts of the code base are not relying on shim-specific behaviors.</p>
<h2 id="further-readings"><a class="markdownIt-Anchor" href="#further-readings"></a> Further Readings</h2>
<p>But how do you implement the new alert API on iOS 14? Find out more at <a href="/en/2023/04/17/backporting-swiftui-apis-with-result-builders/" title="Backporting SwiftUI APIs with Result Builders">Backporting SwiftUI APIs with Result Builders</a>.</p>
2023-04-13T23:52:50.000Zhttps://apollozhu.github.io/en/2022/01/15/sideload-kde-connect-ios/Sideload KDE Connect iOS<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><div class="note success"><p>For general audience, please use the official <a href="https://apps.apple.com/app/kde-connect/id1580245991">App Store</a>/<a href="https://testflight.apple.com/join/vxCluwBF">TestFlight</a> releases.</p>
</div>
<span id="more"></span>
<div class="note warning"><p>This is intended for contributors outside of K Desktop Environment e.V. development group to test their code on a physical device before opening a merge request. This process should theoretically work even if you don’t have a paid Apple Developer account, though I’ve never tested.</p>
</div>
<div class="note danger"><p>THE INSTRUCTION IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE INSTRUCTION OR THE USE OR OTHER DEALINGS IN THE INSTRUCTION.</p>
</div>
<ol>
<li>Download KDE Connect iOS source code from <a href="https://github.com/KDE/kdeconnect-ios">GitHub mirror</a>/<a href="https://invent.kde.org/network/kdeconnect-ios">KDE Invent</a></li>
<li>Open <code>KDE Connect.xcodeproj</code> in Xcode
<ol>
<li>In <code>Build Settings</code> for target <code>KDE Connect</code>, delete <code>Code Signing Entitlements</code> (but do not delete the entitlements file)</li>
<li>In <code>Singing & Capabilities</code> for target <code>KDE Connect</code>, change the <code>Team</code> and <code>Bundle Identifier</code> so the project builds for <code>Any iOS Device</code>.</li>
<li>In <code>Products</code> folder, right click on <code>KDE Connect</code> (which shouldn’t be red) and select <code>Show In Finder</code></li>
</ol>
</li>
<li>In terminal, navigate to the folder containing <code>KDE Connect.xcodeproj</code></li>
<li>In terminal, type the following commands <em><strong>line by line</strong></em> (other than comments starting with <code>#</code>). See <a href="#references">References</a> section about what each of these lines do:<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">build=<span class="comment">#drag the KDE Connect.app here from Finder</span></span><br><span class="line">security cms -D -i <span class="string">"<span class="variable">$build</span>/embedded.mobileprovision"</span> > provision.plist</span><br><span class="line">name=$(<span class="built_in">basename</span> <span class="string">"`pwd`"</span>)</span><br><span class="line">/usr/libexec/PlistBuddy -x -c <span class="string">'Print:Entitlements'</span> provision.plist > entitlements.plist</span><br><span class="line"><span class="comment"># Note that extra ' is added because name contains whitespace in path</span></span><br><span class="line">/usr/libexec/PlistBuddy -x -c <span class="string">"Merge '<span class="variable">$name</span>/<span class="variable">$name</span>.entitlements'"</span> entitlements.plist</span><br><span class="line"><span class="comment"># Replace `YOUR NAME (TEAM)` with the actual value of your Apple Development Certificate name (found in KeyChain Access)</span></span><br><span class="line">codesign -d --entitlements entitlements.plist -f -s <span class="string">"Apple Development: YOUR NAME (TEAM)"</span> <span class="variable">$build</span></span><br></pre></td></tr></table></figure>
</li>
<li>Place the <code>KDE Connect.app</code> in a folder named <code>Payload</code>, zip the <code>Payload</code> folder, and (re)name it <code>KDE Connect.ipa</code></li>
<li>Install self-signed <code>KDE Connect.ipa</code> on your own physical device for testing (requires jailbreaking or apps like Sideloadly)</li>
</ol>
<h2 id="references"><a class="markdownIt-Anchor" href="#references"></a> References</h2>
<ul>
<li><a href="https://fotidim.com/carplay-apps-without-entitlements-in-an-actual-car-37a708758262">CarPlay apps without Apple’s blessings on a real car</a></li>
<li><a href="https://gist.github.com/bananita/8039021">How to convert *app to *ipa</a></li>
</ul>
2022-01-15T21:00:42.000Zhttps://apollozhu.github.io/en/2022/01/01/feminine-penis/Somewhat Academic Study of Feminine Penis<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">
<script id="hbeData" type="hbeData" data-hmacdigest="45b1b1de31bf4859c104f27c3d6043fb2499c6eff04c8c1dc701ac62b8061236">b3a5d29b5fccde67004ada25095c88244b8a1464a16d6acc9c5e6c072883b702f1294f8bce41f2cfcc0dc15dc95f31e90fa4cc1734038fea825addd6ce61e71521e12ad0ef3dcb55f4697481457393e86ddd7ce8e685269bf67ae5e81f1ad051153853acdaec513b20675c3eb315cbda336eef8c6fad8322429bedb006945b7ebae27d1ca68361328b49cb0b1162f2cb2847aa3312cfc80b68b87c2a27ea1c2c1b88e963c93592c6062c9f7f91be5ebf8015d81d0da26aed2dfdf9ffd2391d34653d55404b81bb2c455b3e4a7e87111ff5f5dde71562df2d5e7e0119e9dae14dbe80c1bf8e5e7eb1186c1f7d06f73e01178a094c934ca97c9369733d879993b30f1547e506fa58365e067118dd976df7727d8b0914b30e901f3c7b98d93cb30eea4cd5e461ddf816ec715e12445744e5dda619ca1374590c63829db752588f88b1400b7654e42a21a2d30e79f9c80546f7f7c065b43feeb4bc64e35db94cd237056c5a105910a88d4eae549e5f3968290081de32f59f7afea866bf8041dfeeb823c29072cc359a10f51c609914cea5c73042e3aec9b3d03af9a37d066dc638fce098a54470fb6c63e0d39b8dbf57ce05d720e1c6fc1f90c6bf9aebd2fb4bae7975f89392098ce8f1091950644d7fadf0348fbfe88eefa064bed0d6b7c03e0f9f176e8b759c148ad43cdedfbcb39efec1e83dbe70e7a44666c676d1ebebaa5d6b13c4cfd838a7582712fe553c66bdd540c2168e35476fbbb4a5372ce10f15bbe37be69dca2074487c0843a8ef99962e1f9766e48973f02ddec5e31fdafc9dde1718fdf2d927d0ee60821fb4a99ba381f10f6b687872c83ff0317a851f1c8f228ebbb0fbbc8b1de159583fd4def775292f1e2ccdd0b96798a5239e759a4809a4340b238d35313a7fa7205cfbf4af9a402e517b3ebb5ab51b9f35156bae57b44113f9e716e69f1d0e2fadee78bd4a0f4427b0373ec247f1b8b6f584473901810b84b324b9847e6beaa406783062f3ba50b08da9573b4fbc5fe43e84d247c58f9a2bbbb52778a8d11606722fc612b741bf2ad7d21edef764c5d65f09028cb8f014b7e7e36edbbb21befa4337edb747148ce1ecdeddca981a10210ea8ea0a97a5b95891ceaeee1fcbeb361a22f498885fce68366a922a8cce51a7da80a9f8d2eb987fe5da0e54c43977ecf5423e4c240f37963db05f1945006e626eab3f1153a08cedd44d8d56c5d76ec745509d8d9ad813ff5ec95065a4fd527ae9b5017d3a2cfc4c562db321379105dd796235d067d2e412debc5db3ac4cec32e13c45751c2c0793b60a9d4bf43f7ed6d1e54743e220a556c0b305b2a22e1ea3102f04e81e74274ad33b6dd97aaf5a805c6b9f68019b87150997c78624cc18dbc29b99597e468491d9b875080510e13d4e051b2eafc6dc7a91115d92d150c7b9c05e2cf7995f5156ee2d58c51b9898dcb3c063a9bca57c8d61234a17d373312d257a4a54299b55edb792599e13b8215566780acfb5041c8a3c48ab087e8df0f5510b37722a6be09e213e584a35ddbc1e7c9b57f92e8b04103475d83bd3871c3a2473d52941e28b9ffc278431b8218255ea32adf21cc37149d18e7f0ceacad85008c9454ac9e8025f3ffef6aed1828c2b29ca6ec848afec7fe9fdf08828c82a61250a88e4552b3c8ad9011ccfd632975a03451eabc6bd913af7d985f96939c53d47d834a25b1c7facdd4f50c3cb294e7bba02f4fd9e13da8e3c7c59e05201535a929f68906e6e16a82f61ec773154e5fa4a97f733fc5033fc9c81928edda72fb9847f8de1dea93f5d71ffd0abf3e44b22f4e7fd12100067083591ec43e8eebb5e0aa98d88fa75de7754136fe699aae244ced412c6d3a3b6b6816afe25e9147f3075b94580e71caaf3cd4b838d8ebee83ecd41118f168eef50f40667145cd81f752eb91e9a4fc7b6b140e69d92f6161208bac5947f2f781850d2cabab4d7d1dc675a4db4a8c6fa6bffa69473e4912e8d2a0710521e779739d129dd251ce584dba52eff51eb771159babb9de5262a08632d574e3993add282b9b551221ef580449af5e34c3e7b0e98fd28eee7f9c33e35aa696baee272b1766b8fbb34d0686492e5fcbf3e7ed9ff16a18124e90d34f5d39cf464047151a1dc4649b476eda28a8844f2c3aa5e166afac075083196cbc8af78f4b8b836f415f10e94ab9eb6a71fc4f71df14857b19176f02f8937535118257371599c7b75012bf0ac883be38c7363d8fa2656679a7ccd56b40c17011cf15ad2a8016b536b73e14ef3a5688ef72da19eb5e44292cbbd52d245c769fc48915a7e2596cc644ebb1351d8e89c8d5e89d80232a82e9ff8c9a97d3d015613f8b7557d423a3b3c331f8cce006040b9a92ec71d763a7e1795245bcfbdd9ebfa62a013ef3aa62f8757e18a6202b60f0a24f06b7080df858a1e8867529d3ba962f73ae02a912bb62b978d20820a1681e06798a153be9ff659049d10b3a361959de248f0d6f2ac2bb3d452f61df11a01a28dd60483c851fd81aecb4758f0a6b449ef1d1ae1ab60c3476b7f279a875d5202184cc0fa11413dbdea7237c80fe90b8f58ca414d7d13276df8fbee27fdbe5a103d7afeb64860e56fc62e0f95c8591b554f364ae66f113a365ef66fcb78138a419cc7c97baec5aa816eb7cdf028af61fa3ca558c6a15c37e598d13629c8da0f3091d4b03d82249891ae4690804aae5b89685ad22b17f85363f49b5fccf2a321112f7b96706159dfeaea37e6a4503da1171d1b01cb57028050685e01177828e5f671d0402a499ae7c58704f03c7baf4f14e7a9ba4717cf6bc8957b8b95ff641dfc5ace06113d753e9e00ffb9307497cd4088c56fe30bac8987147bfe04f44ca9e0b21c432a79beb7fbba54da09a394442373eeb4e77555630ee4b783f515143322204184f1930e81fb901e91e37c82819074dae27aaced5dbba66f972655484b38a5e194aefed009029e01cca539b6b764f6b31141fbc0de1e9456309ab7279568d283d6a30c7ce7e02d4e885834f80b9347e8c7674867453bf6d12ea0030af2c96f980e705357f9ba35d36bf56698ff09a370b3ca46d6de47a8aed21b810a9d9469ce6b646ec002ec8b0125fa966eda9335e2c46d6f7d052f79bf5b1346afd246bc27bec0e7970115c44214cad96fb8d1a4a37f2b63df205c99ba7cbd5f65769ad178ae8f71852a40f2acd947be9c4d64b915000282a8bef5e12ab1084f48d554aed38ac250ee395a2b29ac5be435b39375f06f0aa13b8883826117535691a90f38c8733183eb573c4050b0078c2d6b4ba3dac5691666d8dd64d8811069e42c30fa94fed2a90f7a24ca0c5b958f5a1d82c4b3935cf6de0665eaa6d5eee20bc44cdf3800ff50d35f1971a0d9cfb295dc3505bb138bf2ddfc4debe8bace1b609e05f170aa60bd15e0b76e187eb93f0c050d6796c0f8ebf2090c656b637ba34c9ccc2bdd9fff93628cc661425c9a0c1b7f59693458819812015286a980312ab6cbddc7bdecb4d05e148efe2b1cdff2afc78b877de635ee0d554c531285621a2030d89789152849039e01c8c7562801406470099294fb9db2752566ca0ae6662ddfa93061a9947c599cbefa270164d737bb39012a91cdb78e61312b738e43442141a5627085df10596466d9f60569798ed441178670408d36ab3e15e5844b5968f2bb49aa34531097e6413a6229f94dd8622d6adb4e2d20b03391dde253fa9d41e0e0804b8ee0a01c407f39e4ae80d287cace05b8ed39759a6f7d79b5f13cfa8af84fdbb1e2e9fd6ead503a6b7d9a718ab8d15ba3187103488accfae606eb27eba7af83e66a119db6f85c4e7dd74d586988986fadcf775c8feab9c06756ac0a439e5b31a133962fc25daa8ee484593c5d5ec9dd997c6739d7e1c613f63208d4bf53ca2e8243529492581ea0d9e891155f96a5c6c4954616f7365be99a876576de84ff4eab2f22a07fe75488f1753f81908158f0dbc9f863756911cb16685c33bbdd1dd2a7c0d5dc7849b0ba16f2e1a2e1b2a99f4cabb97acef5f97bfef2d8112eb15dfbf15ce76610da6208f5c389ed042732c99943afe5fa79efdc8ea9113dc965a8cf47c8c17400267c753f7e0d48bc5c991f08615d36f6ea1c3ae61acee7258a95c17ad54e20f405be9a3ccf33f7a6682592c23731f6bc2c2fff7cb4d302b0cd10d4d3ed9b79d47c6b4c12297afd4c5dc4cef40308112d9dfe7284ad79ac329c5c7579a183d83ebf04be1b2186300beaf9ba0282a331e21510d14f88afccf0c3fa395ec29bb409f8d44aff072f5d4487382a39ebdfc7dde3a373561c93d904bc6f20d28bec4de798286971284a13771cf678de562eeef36889adc5246b03058c9dd1a16fe76dea81cd3802580d</script>
<div class="hbe hbe-content">
<div class="hbe hbe-input hbe-input-shrink">
<input class="hbe hbe-input-field hbe-input-field-shrink" type="password" id="hbePass">
<label class="hbe hbe-input-label hbe-input-label-shrink" for="hbePass">
<span class="hbe hbe-input-label-content hbe-input-label-content-shrink">Nothing explicit, but type “Continue” to read more.</span>
</label>
</div>
</div>
</div>
<script data-pjax src="/en/lib/hbe.js"></script><link href="/en/css/hbe.style.css" rel="stylesheet" type="text/css">2022-01-01T16:40:33.000Zhttps://apollozhu.github.io/en/2020/12/10/github-university-twilio-quest-easter-egg/Operation Univers(ity) TwilioQuest Easter Egg<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><p>During the <a href="https://github.com/education/github-university-2020">GitHub Universe 2020</a>, I answered the call to an adventure:</p>
<blockquote>
<p>There’s an easter egg within <a href="https://www.twilio.com/quest">TwilioQuest</a>. Your first hint is: “hit the nail on the head.”</p>
</blockquote>
<span id="more"></span>
<h2 id="a-slight-detour"><a class="markdownIt-Anchor" href="#a-slight-detour"></a> A “Slight” Detour</h2>
<p>Since the hint is “hit the nail on the head,” I believe a lot of people have tried to “hit” everything that has even just the slightest connection to either “nail” or “head”.</p>
<p>Me too. I spent countless hours trying to click the head of the 2 people in the welcome screen, that of robot Cederic, the head of the Operator, and many other places. Yet, none of those worked.</p>
<p>Well, time to try reverse engineering. Let’s see if the source code of the app can tell us something.</p>
<div class="note danger"><p>Note: make sure you are allowed to do this by the Terms of Service / End User License Agreement.</p>
</div>
<p>You can view the source code of TwilioQuest by selecting the Help menu, then Toggle Developer Tools.</p>
<p><img src="https://user-images.githubusercontent.com/10842684/101840154-9712b300-3b11-11eb-87e7-b3001729e8d1.png" alt="TwilioQuest with its source code after toggling developer tools" /></p>
<p>For easter eggs/hidden features, the words that I usually start to look for in source code are “easter,” “egg,” “secret,” “found,” and “congratulations.” Since the hint for this one is “hit the nail on the head”, I also tried to search for “nail,” “head,” “hit,” and “click” in all of TwilioQuest’s source files. (Somehow I can never remember how to search for all files using Chrome Developer Tools, so here’s a <a href="https://stackoverflow.com/questions/37685351/chrome-devtools-search-all-javascript-files-in-website/47690078">stack overflow post</a> demonstrating how.) Yet, nothing of particular interest showed up in the results.</p>
<h2 id="nail-in-the-head"><a class="markdownIt-Anchor" href="#nail-in-the-head"></a> “Nail” in the <code>head</code></h2>
<p>When I checked the <a href="https://github.com/education/github-university-2020/commits/main/README.md">modification history of the README.md file</a> (to see if they have accidentally leaked something), a version of it said that “the game will let you know if you’ve qualified!” So I assumed that this must be a feature in the TwilioQuest app itself, revealed by some kind of JavaScript code / hidden chests / etc…</p>
<p>But what if it is not? Since <a href="https://twitter.com/ekuekanshgupta">Ekansh Gupta</a> mentioned about opening TwilioQuest source code on Slack, we’re probably in the right place. But we’ve spent too much time looking for the clue, how could Vicdoja solve the puzzle in less than an hour after receiving the hint on Slack? It must be something that’s directly related to the hint, something obvious that we’ve been ignoring.</p>
<p>Well, indeed there was. There’s something that we’ve ignored so far: the <code>head</code> HTML tag seen in the first screenshot. Because there’s no “code” in the <code>head</code> tag, I never considered it to be the head that I was looking for. With no where else to examine, I expanded the <code>head</code> tag by clicking that triangle to its left:</p>
<p><img src="https://user-images.githubusercontent.com/10842684/101842641-7a2cae80-3b16-11eb-823d-b4251724b0d8.png" alt="There's a comment saying follow the white rabbit with a link to GitHub gists" /></p>
<p>We finally hit the nail on the head and can “follow the white rabbit” to continue our adventure.</p>
<h2 id="more-puzzles"><a class="markdownIt-Anchor" href="#more-puzzles"></a> More Puzzles</h2>
<script src="https://gist.github.com/kwhinnery/b3cbc250fa1df65cc3c36ca39495d486.js"></script>
<p>The file is named “<a href="https://gist.github.com/kwhinnery/b3cbc250fa1df65cc3c36ca39495d486">egg.md</a>” and the description says “GitHub Univers(ity),” indeed this is the easter egg that we’ve been looking for. But what could this long line of cryptic text possibly mean?</p>
<p>If you scroll to the end of the line, you’ll see “<code>==</code>”. That’s a classic sign of Base64 encoded text, so I just searched for an online Base64 decoder and decoded this weird line of characters, yielding:</p>
<div class="note info"><p>To complete the egg hunt for GitHub Univers(ity) 2020, email <a href="mailto:kwhinnery@twilio.com">kwhinnery@twilio.com</a> with a subject line containing [EGG HUNT], with the answer to this question:</p>
<p>What game, written by Warren Robinett, is credited as having the first-ever easter egg?</p>
</div>
<p>Thanks to the Internet and technologies we have today, this should be a simple question to answer.</p>
<div class="note warning"><p>I wanted the adorable <a href="https://github.myshopify.com/products/octoplush">Octoplush</a> for so long, and <a href="https://www.twitch.tv/videos/832648555">it’s finally on the way</a>!</p>
<p><img src="https://cdn.shopify.com/s/files/1/0051/4802/products/Octoplush_d76ba290-d65b-40b9-a675-cfc3afa76b6e_large.JPG" alt="Octoplush is a cuddly Octocat" /></p>
</div>
<h2 id="cont"><a class="markdownIt-Anchor" href="#cont"></a> cont.</h2>
<p>Although <a href="https://githubuniverse.com/">GitHub Universe</a> 2020 is over, it’s not too late to start contributing to the open source community. Tryout “<a href="https://www.twilio.com/quest/learn/open-source">The Flame of Open Source</a>” training mission in TwilioQuest to help you get familiar with the process, and adventure on! Together, we can save the flame of open source 🔥.</p>
<p><img src="https://user-images.githubusercontent.com/6633808/101407837-c50eb200-38db-11eb-90ff-4888b5598de0.png" alt="Operation Univers(ity), an epic journey to save the flame of open source" /></p>
2020-12-10T16:42:48.000Zhttps://apollozhu.github.io/en/2020/08/07/email-to-zhuzhiyu-at-cs-washington-edu/Beyond the sky, into the nyaamament!<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><p>Congratulations.</p>
<span id="more"></span>
<p>I know you have so many questions and concerns about future. You used to think you know what exactly you want to study, but as you learned more (about CSE and yourself), you start to realize how little you know, and how many things you want to explore. I can’t give you an answer as to exactly what’s the right direction, but I know one thing you should always do: taking a step forward, no matter how small.</p>
<p>Right now, the world is quite crazy, and people are divided. You should never let negative feelings overwhelm you and widen the gap between communities. And remember, though been an effective tool, technology is not the golden key to every problem. It’s gonna be hard, but that’s fine. Just never give up.</p>
<p>Sincerely,<br />
Apollo | 朱智语<br />
Paul G. Allen School of Computer Science & Engineering<br />
University of Washington - Seattle, Class of 2023?</p>
2020-08-07T04:33:09.000Zhttps://apollozhu.github.io/en/2018/07/10/cs193c-memes/JavaScript "Memes" from CS193C<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><h2 id="is-html-a-programming-language"><a class="markdownIt-Anchor" href="#is-html-a-programming-language"></a> Is HTML a Programming Language?</h2>
<blockquote><p>We’ll be using HTML, CSS, and JavaScript. JavaScript is the programming Language.</p>
<footer><strong>Patrick Young</strong><cite>Lecture 1</cite></footer></blockquote>
<h2 id="wtf-javascript"><a class="markdownIt-Anchor" href="#wtf-javascript"></a> WTF, JavaScript?</h2>
<blockquote><p>Because JavaScript is JavaScript, things can be totally wrong but still legal.</p>
<footer><strong>Patrick Young</strong><cite>Lecture 5</cite></footer></blockquote>
2018-07-10T14:55:50.000Zhttps://apollozhu.github.io/en/2018/06/11/computer-science-education/The Past, Present, and Future of Computer Science Education in Virginian High Schools<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><p>Before we start, let me ask you a question: For the public high schools of Fairfax County in Virginia, approximately what percentage of them do not have any computer science related courses?</p>
<span id="more"></span>
<p>You might guess it would be around 15% or 25%, but what if I told you that <em><strong>half</strong></em> of the FCPS high school students can’t learn programming at school? With the introduction of self-driving automobiles and all the developments in machine learning and artificial intelligence, the availability of these related courses should be front and center. Not only because some students may want to learn how to write those apps, but also the requirement for more and more employees in various sectors to have computer skills.</p>
<p>Therefore, Virginian high schools should prioritize funding for computer science programs of cutting-edge technologies by updating current curriculums, supplementing new courses, and training more competent teachers to best meet the job market demands.</p>
<h2 id="a-sneak-peak-at-the-history"><a class="markdownIt-Anchor" href="#a-sneak-peak-at-the-history"></a> A Sneak Peak at the History</h2>
<p>The first computer was invented in the United States, but do you know what’s more fascinating? The growth of computer-related jobs. According to the report from the Bureau of Labor Statistics of the U.S. Department of Labor, there has been a continuously rising demand for computer scientists, even during the recession period between 2007 and 2009. Not only is it independent of the current economic trends, the job outlook for these fields predicted by the report is very promising. In the upcoming 10 years, there will be 24% more jobs for software developers and 28% more for information security analysts. That is 3 or even 4 times the 7% average increase of all jobs.</p>
<p>So do we not have any CS courses offered at high schools? Well, we do. The AP Computer Science A class regulated by the College Board is one of them. Unlike the other courses designed by high schools, APCSA has been updated several times to reflect the changes in the current trends. Initially, back in 1984, this class teaches students Pascal. Then in 1999, they decided to switch to C++, and later in 2003, they switched to Java, the top language used across all computer programs. However, they did not update the curriculum since 2014 to reflect the major changes in the Java programming languages, and basically, the students are now learning the wrong “facts.” The outdated materials frustrate students and require students to do much more work than they need if they know about the recent changes. It’s like you could get your hands on an iPhone X, but you have to stick with a slow iPhone 6 without even your battery replaced.</p>
<p>Indeed, some of the high schools already have a variety of programming classes offered for students of different levels. For example, Oakton High School, a typical public high schools in Fairfax County, Virginia, teaches Information Systems, Programming, Webpage Development, APCS A and Principles, and the advanced variants for some of these classes. They provide students with many choices, but none of them teach students the new skills that tech companies are looking for.</p>
<p>Let’s look at the web development class. Its textbook teaches students how to use XHTML, which is known for its poor compatibility and had been abandoned a long time ago. The current industrial standard is HTML 5, with much more powerful features and straightforward “grammar.” Concerned, I asked the teacher how the county plans to update the course curriculum. The teacher — Larson — gave me an unexpected answer. They are taking it away sooner rather than later, for they believe students are not interested in it and the class itself is too hard. I think the county doesn’t really understand why the students are not signing up for that class. While the difficulty might be one of the reasons, the main cause is likely that the class really is not sufficient to prepare them for their future jobs.</p>
<p>Even worse, around 50% of the FCPS high schools don’t offer a single computer science class. Sharon Wu is a current member of the Career and Technical Education Advisory Committee. She said, in fact, FCPS has no budget to hire more CS professionals or offer more classes. Even at Thomas Jefferson High School for Science and Technology, one of the top-ranked high schools in Virginia, students are seeking summer programs because “school is too easy and no advanced stuff is taught in class.”</p>
<h2 id="whats-happening-now"><a class="markdownIt-Anchor" href="#whats-happening-now"></a> What’s Happening Now?</h2>
<p>Maybe these issues aren’t important in the first place — students do not realize how important it is for them to be able to use a computer. Many high school students these days are obsessed with smartphones, but at the same time, they don’t know how to use a computer. The school libraries have to teach them how to find the most relevant sources in the databases, the tech office has to help them connect to the school Wi-Fi, and some even need help with using word processing softwares to complete their assignments.That’s because they don’t know what they can do with computers and programming. Students who do know are taking classes on their own to acquire knowledge for brighter futures. These motivated students are willing to do regardless of the consequences, whether it means traveling to a local college on a regular basis or giving up some of their homework time. I do the same, and for me, the motivation came from Masako Wakamiya. She is an 82-year-old Japanese woman who learned programming on her own after retirement. She made several apps to teach people traditional culture and handkerchief making. She proved to me — and the world — that everyone, no matter their gender, age, or race, can master programming. Then could we utilize the skills as our “wings” in daily life, exploring a wider world that we could not have imagined before.</p>
<p>However, we do want to have support from our schools. Students were really excited when Oakton (for example) announced the new Cyber Security elective.</p>
<p><img src="https://user-images.githubusercontent.com/10842684/46906595-f47c2c80-ced3-11e8-984e-5ba26a913e12.jpg" alt="Students trying to penetrate into the classroom." /></p>
<p>The information session was crowded with students of all grade levels. The room couldn’t fit them all, so many just stood outside, trying to grasp any information they could hear. This is an exciting change, but with it comes more problems to solve. Too many students sign up for this class and the teacher, Mr. Larson, will need to balance out his schedule with all other programming classes. Even after taking out the webpage development class, he still needs help from another teacher. Without an increase in funding qualified teachers, some students will need to take their alternative instead.</p>
<h2 id="warningtodo"><a class="markdownIt-Anchor" href="#warningtodo"></a> #warning(TODO)</h2>
<p>We could do nothing, but what we can at least try to resolve these issues?</p>
<p>The most apparent solution is to use up-to-date materials in class. This will not be as easy as it sounds. Textbooks might need to be replaced more frequently than those for other subjects, teachers need to spend more time planning their classes to incorporate the new materials. In case there isn’t a textbook ready for use, teachers can consult other free, but at the same time professional, resources online. For example, the authors of The Swift Programming Language ebook are constantly updating it to demonstrate the new features and replacing examples used in the book with more relevant ones. Is this too hard? Maybe, but the AP US History exam was modified almost immediately after the 2017 AP Exam. If the history teachers can handle the changes, I believe our Computer Science teachers can do the same.</p>
<p><img src="https://user-images.githubusercontent.com/10842684/46906599-f7771d00-ced3-11e8-9712-2995d94ac2d2.png" alt="A map from code.org showing the states that require all high schools to have CS classes." /></p>
<p>Virginia already allows rigorous computer science courses to satisfy core high school graduation requirement and allocates funding specifically to computer science, but we can push this further. The state can make computer science fundamental to K-12 education. Congress’ 2018 budget has dedicated $50 million per year for STEM and the new grant guidelines prioritize funding for computer science in schools. With that and the state standards for computer science education, we can require all schools to teach computer science in Virginia.</p>
<p>If all of our future generations can learn how to use the state-of-the-art technologies, they’ll be able to use programming to</p>
<blockquote class="blockquote-center">
<p style="font-size: 1.3em;font-weight:bold">Create a world like no one has seen before.</p>
<p>— <em>Danielle Feinberg, Director of Photography for Lighting at Pixar</em></p>
</blockquote>
<hr />
<h2 id="side-notesreferences"><a class="markdownIt-Anchor" href="#side-notesreferences"></a> Side Notes/References</h2>
<p>Danielle Feinberg and her team use <strong>programming</strong> to generate the astonishing scenes we see in Pixar <strong>movies</strong>, such as the Marigold Bridge in Coco and the Scottish forests in Brave. For more, see WWDC18 lunch session <em>The Art of Science: Bringing Pixar’s Imagined Worlds to Life</em>.</p>
<p><a href="http://Code.org">Code.org</a> is always trying to expand CS education to more students. Their <a href="https://docs.google.com/document/d/15zBdBbXUA-yEzxEq0VeWAEb9nXuGjmNFWNrYp6UdM8U/edit">email</a> directed me to a <a href="https://code.org/files/Making_CS_Fundamental.pdf">solution</a>.</p>
<p>Dr. Wu really helped me a lot, and I’m looking forward to continue working with her. And thanks to Mr. Lau and Mr. Larson of Oakton High School in giving me insights of the difficulties and realities the teachers face, allowing me to analyze the issues from a different perspective.</p>
<p>I highly recommend you to check out the YouTube video “<a href="https://www.youtube.com/watch?v=gUjXiYtOC7Y">Now Is the Time to Get Your Own Wings</a>” by Wasako Wakamiya. It’s definitely not a story you can hear about every day.</p>
<p>Other information is from the National Science Foundation (College Board), and the US Department of Labor.</p>
<p>Thanks to editor <a href="https://www.uscecc.org/wuzup-team-bio">Jiachen Sun</a> for revising my <a href="https://medium.com/@Apollonian/the-past-present-and-future-of-cs-education-in-virginia-high-schools-88b892d8c320">crappy first draft posted on Medium</a>. This polished version is also available through <a href="https://www.uscecc.org/computer-science-education">Wuz Up!</a>, a multi-cultural group aimed at teaching newcomers about American culture, values, and lifestyle.</p>
2018-06-11T10:57:09.000Zhttps://apollozhu.github.io/en/2018/03/15/wwdc18-scholarships-info/WWDC18 Scholarships Information<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><blockquote>
<p><a href="/2018/03/15/wwdc18-scholarships-info/">阅读中文版本</a></p>
</blockquote>
<details>
<summary>Wait, before we start, what is WWDC?</summary>
<p>I’ll add my description soon, but for now, check out the <a href="https://developer.apple.com/wwdc">official website</a>.</p>
</details>
<p>Thank you all for being interested in <a href="https://developer.apple.com/wwdc">Apple’s Worldwide Developer Conference</a> and <a href="https://developer.apple.com/wwdc/scholarships/">this scholarship opportunity</a>. I hope all of us could go together, to learn, and have fun!</p>
<p>I know this article is a little bit long, but please read through this carefully before you start. If you have any questions, just ask me through messenger, or in the comment area below.</p>
<blockquote>
<p>I’ll be constantly updating this, and the Chinese version is available <a href="https://apollozhu.github.io/2018/03/16/wwdc18-scholarships-info-cn/">here</a>.</p>
</blockquote>
<span id="more"></span>
<h2 id="important-dates"><a class="markdownIt-Anchor" href="#important-dates"></a> Important Dates</h2>
<table>
<thead>
<tr>
<th style="text-align:right">Date</th>
<th>Event</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:right">April 1, 20:00 EDT</td>
<td>Submission Due</td>
</tr>
<tr>
<td style="text-align:right">April 20</td>
<td>Announce Status</td>
</tr>
<tr>
<td style="text-align:right">June 3-8</td>
<td>Orientation + WWDC!</td>
</tr>
</tbody>
</table>
<h2 id="general-information"><a class="markdownIt-Anchor" href="#general-information"></a> General Information</h2>
<p>Please read the <a href="https://developer.apple.com/wwdc/scholarships/">description</a> carefully, as well as the <a href="https://developer.apple.com/wwdc/scholarships/terms/WWDC18-Scholarship-Terms-and-Conditions.pdf">terms and conditions</a>. In summary, you are required to write a Playground – an interactive program – that is creative and technically accomplished.</p>
<h2 id="things-to-get"><a class="markdownIt-Anchor" href="#things-to-get"></a> Things to Get</h2>
<p>You do <em><strong>NOT</strong></em> need a paid Apple Developer Account. Do you know what’s better than that? You’ll get one year of Apple Developer membership if you win!</p>
<p>If you have a Mac, download <a href="https://itunes.apple.com/app/id497799835">Xcode from Mac App Store</a>, or if you have an iPad, download <a href="https://itunes.apple.com/app/id908519492">Swift Playgrounds from App Store</a>, or if you have a Windows, get a virtual machine or whatever that works.</p>
<h2 id="learn-swift"><a class="markdownIt-Anchor" href="#learn-swift"></a> Learn Swift</h2>
<p>If you have an iPad, I highly recommend you to go through one of those “Learn to Code” playgrounds to get a general idea about what a legit playground should be like, in addition to the Swift programming language itself.</p>
<p>At the same time, everyone by now should have either an iOS device or a Mac, please open (i)Books and get <em><a href="https://itunes.apple.com/book/id1002622538">The Swift Programming Language</a></em>. You can always choose to <a href="https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/index.html">read it online</a> as well.</p>
<p>Most of you are already familiar with Java, so reading just “A Swift Tour” should be adequate for you to understand this simple programming language. For those of you never learned programming before, just scan through that, and chapter 2 (Language Guide) will answer your questions.</p>
<p>You do <em>NOT</em> need to read chapter 3 (Language Reference) and 4 (Revision History).</p>
<h2 id="general-stuff-to-learn"><a class="markdownIt-Anchor" href="#general-stuff-to-learn"></a> General Stuff to Learn</h2>
<h3 id="i-want-to-write-a-2d-game"><a class="markdownIt-Anchor" href="#i-want-to-write-a-2d-game"></a> I Want to Write a 2D game</h3>
<p>You should learn <a href="https://developer.apple.com/spritekit/">SpriteKit</a>.</p>
<h3 id="i-want-to-write-a-3d-game"><a class="markdownIt-Anchor" href="#i-want-to-write-a-3d-game"></a> I Want to Write a 3D game</h3>
<p>You should learn <a href="https://developer.apple.com/scenekit/">SceneKit</a>, but I hope you’ve already had some sense of how 3D works and where to get your 3D models. A bonus for you, <a href="https://developer.apple.com/videos/play/wwdc2017/605/">Apple talked about using SceneKit in the iPad version of Swift Playgrounds</a>.</p>
<h3 id="otherwise"><a class="markdownIt-Anchor" href="#otherwise"></a> Otherwise</h3>
<p>Well, <a href="https://developer.apple.com/documentation/uikit">UIKit</a> itself can do a lot of stuff. To get started, follow <a href="https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/">Start Developing iOS Apps (Swift)</a>.</p>
<p>If you have time, you may also want to have a general understanding of how <a href="https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS">view controllers work</a>, maybe more about <a href="https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/TableView_iPhone/AboutTableViewsiPhone/AboutTableViewsiPhone.html">table views</a>, or even <a href="https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Introduction/Introduction.html">iOS Apps in general</a>.</p>
<h2 id="more-about-playground"><a class="markdownIt-Anchor" href="#more-about-playground"></a> More About Playground</h2>
<p>No matter what, you should read the <a href="https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_markup_formatting_ref/">Markup Formatting Reference</a>. Your Playground will look a lot better with this in conjunction with <code>CustomPlaygroundQuickLookable</code>/<code>CustomPlaygroundDisplayConvertible</code>.</p>
<h3 id="mac-xcode-and-playground"><a class="markdownIt-Anchor" href="#mac-xcode-and-playground"></a> Mac, Xcode, and Playground</h3>
<p>It was first <a href="https://developer.apple.com/videos/play/wwdc2014/408/">introduced back in 2014</a>, and later in 2015 you can use the format mentioned above to <a href="https://developer.apple.com/videos/play/wwdc2015/405/">author rich Playgrounds</a> to better instruct your users. Here is <a href="https://developer.apple.com/library/content/samplecode/StarterPlaygroundBook/Introduction/Intro.html">a simple Swift Playground Book</a> for you to get started, and you can also find other interesting ones from the <a href="https://developer.apple.com/swift/blog/">Swift Blog</a>, although many of them would be outdated and require some changes for them to work.</p>
<h3 id="ipad-and-swift-playgrounds"><a class="markdownIt-Anchor" href="#ipad-and-swift-playgrounds"></a> iPad and Swift Playgrounds</h3>
<p>This app is first <a href="https://developer.apple.com/videos/play/wwdc2016/408/">introduced in 2016</a> and <a href="https://developer.apple.com/videos/play/wwdc2017/408/">updated again last year</a>. iPad Playground has many features that a normal Xcode Playground doesn’t have – Cut Scenes written in html (a great place to inform your user what’s this chapter about), cover images, vocab lists, etc. To fully utilize those features, please read the <a href="https://developer.apple.com/library/content/documentation/Xcode/Conceptual/swift_playgrounds_doc_format/">Playground Book Format Reference</a>, and experiment with <a href="https://developer.apple.com/library/content/samplecode/TalkingToTheLiveView/Introduction/Intro.html">this sample</a> that allows you to send messages to a Swift Playground live view and saving data to its key-value store.</p>
<h2 id="analysis"><a class="markdownIt-Anchor" href="#analysis"></a> Analysis</h2>
<p>Remember that your playground will be judged offline, the program can <em><strong>NOT</strong></em> require an account for sign in, and they’ll only spend 3 minutes in judging it, so think about what you are going to do. Even without thinking I can tell you many people will be doing <a href="https://developer.apple.com/arkit">augmented reality</a> and <a href="https://developer.apple.com/coreml">machine learning</a>; you can not imagine how easy it is to implement those fancy but scary stuff with ARKit and Core ML. Well, try to be creative, add some graphics and audios, and incorporate some of Apple’s new technologies (even if they didn’t mention about that)…</p>
<p>For the first time, you are allowed to use open source frameworks (providing that you included their licenses correctly and explained why). Nonetheless, what you are going to submit is not just a normal program. I think these are some reasons why Apple prefers Playground over normal apps, and maybe you want to address some of them:</p>
<ol>
<li>user will be directed about what to do and informed of what is expected</li>
<li>it provide an interactive way for the users to <a href="https://developer.apple.com/videos/play/wwdc2017/416/">learn things through programming</a></li>
<li>it sparks users’ interest in coding and encourages further participation</li>
<li>…(many more to add)</li>
</ol>
<p>Also, the “Beyond WWDC” essay is very important. You should explain, in 500 words, how you share your coding knowledge and enthusiasm for computer science with others. Spend some time on this and revise it several times.</p>
<p>However, that doesn’t mean the playground itself isn’t important. There were many amazing playgrounds, such as <a href="https://www.youtube.com/watch?v=cq_zLMKB-SE">this one here</a>, but the quality of the <a href="https://www.youtube.com/playlist?list=PLl469UE7Uwr0bdon2CvnpxmQs16qu4nkf">other ones</a> varies. So my suggestion is analysis why some of them got accepted and some got rejected, see if you can resonate with <a href="https://itunes.apple.com/story/id1358780266">former winners</a>, and just try your best.</p>
<p>If you’d ever ask me if it’s hard, I’ll answer yes but <em><strong>DOABLE</strong></em>. Just make sure you don’t copy any others’ code – the <a href="https://github.com/wwdc/2017/issues/7">2048 playground</a> from <a href="https://github.com/wwdc/2017">last year’s submissions</a> was <strong>rejected</strong> for this reason.</p>
<blockquote class="blockquote-center">
<p>Everything is doable if you try.</p>
<p><strong>Mr. Lau</strong></p>
</blockquote>
<p>Good luck.</p>
<p>– Apollo (a.k.a Zhiyu Zhu, last year’s scholarship winner for submitting <a href="https://github.com/ApolloZhu/Swifty-Karel/tree/master">Karel the Robot Playground</a>)</p>
2018-03-15T19:42:39.000Zhttps://apollozhu.github.io/en/2018/02/01/meaning-of-life/Paradox, 0x00<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><blockquote class="blockquote-center">
<p>The meaning of life is to find the meaning of life.</p>
</blockquote>
<span id="more"></span>
<div class="note danger"><p>error: variable used within its own initial value</p>
</div>
2018-02-01T22:44:13.000Zhttps://apollozhu.github.io/en/2018/01/30/ap-lang-quarter-3/Freedom?<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><blockquote><p>Any real change implies the breakup of the world as one has always known it, the loss of all that gave one an identity, the end of safety. And at such a moment, unable to see and not daring to imagine what the future will now bring forth, one clings to what one knew, or thought one knew; to what one possessed or dreamed that one possessed. Yet, it is only when a man is able, without bitterness or self-pity, to surrender a dream he has long cherished or a privilege he has long possessed that he is set free—he has set himself free—for higher dreams, for greater privileges.</p>
<footer><strong>James Baldwin</strong><cite><span style=font-style:normal>“Faulkner and Desegregation”</span>Nobody Knows My Name</cite></footer></blockquote>
2018-01-30T15:59:49.000Zhttps://apollozhu.github.io/en/2017/08/30/ap-chem-survey/Explosive AP Chemistry Survey<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><p><img src="https://user-images.githubusercontent.com/10842684/29992768-89b5b8d2-8f71-11e7-99db-116541df381a.png" alt="Finish the prompt: When I think about AP Chemistry, I am excited about... Explosion! Finish the second prompt: When I think about AP Chemistry, I worry that... It actually explodes." /></p>
<p><a href="http://konosuba.com/"><img src="https://pa1.narvii.com/6354/bd84d66c323ce1eb9a4612b792c0dbba7b72a8b9_hq.gif" alt="Explosion!" /></a></p>
2017-08-30T22:08:28.000Zhttps://apollozhu.github.io/en/2017/08/30/a-1000-times/A 1000 Times<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><p>I saw myself through the lyrics of this song, which we were asked to analyze on the first day of AP Language & Composition class:</p>
<blockquote class="blockquote-center">
<p>I had a dream that you were mine<br />
I’ve had that dream a thousand times</p>
</blockquote>
<div id="aplayer-aMFcsXvq" class="aplayer aplayer-tag-marker meting-tag-marker"
data-id="468738969" data-server="netease" data-type="song" data-mode="circulation" data-autoplay="false" data-mutex="true" data-listmaxheight="340px" data-preload="auto" data-theme="#66ccff"
></div>
2017-08-30T06:37:09.000Zhttps://apollozhu.github.io/en/2017/08/25/apcsab-survey/Advanced CS Student Survey<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><blockquote><p>Dear Advanced APCS students,</p>
<p>In order to provide an excellent learning environment for you in this coming school year, I would like you to help me answer the following questions, be as specific and detailed as possible, so that I can do a better job in terms of fulfilling your needs. Thank you for your time.</p>
<footer><strong>Mr. Lau</strong></footer></blockquote>
<span id="more"></span>
<h2 id="why-did-you-sign-up-to-take-this-course-be-specific"><a class="markdownIt-Anchor" href="#why-did-you-sign-up-to-take-this-course-be-specific"></a> Why did you sign up to take this course? Be specific.</h2>
<p>Just interested; to learn.</p>
<h2 id="what-do-you-expect-to-learn-from-this-course-if-you-know-nothing-about-the-curriculum-just-brainstorm-by-yourself-and-tell-me-something-that-you-want-to-learn"><a class="markdownIt-Anchor" href="#what-do-you-expect-to-learn-from-this-course-if-you-know-nothing-about-the-curriculum-just-brainstorm-by-yourself-and-tell-me-something-that-you-want-to-learn"></a> What do you expect to learn from this course? If you know nothing about the curriculum, just brainstorm by yourself and tell me something that you want to learn.</h2>
<p>Fully understand Big-O notation. Basic algorithms and data structures, and when/why to choose one over another.</p>
<h2 id="what-did-you-do-over-the-summer-that-is-related-to-computing-summer-camp-internship-self-learning-taking-an-online-course-teaching-other-people-please-tell-me-what-you-learned-through-this-experience-be-as-specific-as-possible"><a class="markdownIt-Anchor" href="#what-did-you-do-over-the-summer-that-is-related-to-computing-summer-camp-internship-self-learning-taking-an-online-course-teaching-other-people-please-tell-me-what-you-learned-through-this-experience-be-as-specific-as-possible"></a> What did you do over the summer that is related to computing (summer camp, internship, self-learning, taking an online course, teaching other people)? Please tell me what you learned through this experience. Be as specific as possible.</h2>
<p>Mainly translating Stanford’s Developing iOS 10 Apps with Swift; read The Swift Programming Language (Beta). Wrote an app to post the translated subtitle to online video platform, practiced using recursion, HTTP request, async background queue, and Continuous Integration.</p>
<p>Wrote a raffle app in Kotlin (Google’s new programming language for Android, basically Java), refreshed memory of Swing, learned a little about JavaFX.</p>
<p>Read part of the K&R (The C Programming Language).<br />
Watched a short series of basic tutorials about HTML & CSS.<br />
Watched How GitHub uses GitHub series. Learned several git commands.</p>
<h2 id="please-check-those-topics-that-you-know-something-about-tell-me-something-about-each-if-possible"><a class="markdownIt-Anchor" href="#please-check-those-topics-that-you-know-something-about-tell-me-something-about-each-if-possible"></a> Please check those topics that you know something about. Tell me something about each if possible.</h2>
<ul>
<li>[x] Linked List: Holding a pointer to the previous/next Element. Easier to add/remove, harder to find index.</li>
<li>[x] Recursion: Using itself in the definition of itself. Throws StackOverFlowException.</li>
<li>[ ] Big-O notation</li>
<li>[x] Stack: First (push) In, Last (pop) Out. How I deal with recursive methods.</li>
<li>[x] Queue: FIFO.</li>
<li>[x] Priority Queue: Queue, elements ordered by priority.</li>
<li>[x] Hash Table: AKA Dictionary<K: AnyHashable, V: AnyObject>, mapping Key to Value.</li>
<li>[ ] Heap</li>
<li>[x] Tree: Nodes. May traverse in Pre/In/Post order (if should visit root first).</li>
<li>[x] Binary Search Tree: Each node has max 2 child, with left < this < right, and each child is BST</li>
<li>[x] Graph: (Un)directed edges connecting vertices.</li>
<li>[ ] Depth first search</li>
<li>[ ] Breadth first search</li>
<li>[ ] Quicksort (and basically all other sorting algorithms)</li>
</ul>
<h2 id="your-concerns-about-this-course-be-specific-and-honest-write-as-much-as-necessary"><a class="markdownIt-Anchor" href="#your-concerns-about-this-course-be-specific-and-honest-write-as-much-as-necessary"></a> Your concerns about this course. Be specific and honest. Write as much as necessary!</h2>
<p>Big-O notation sounds/is quite confusing, it took me a long time to understand why merge sort is <code>O(nlogn)</code>.</p>
2017-08-25T20:52:17.000Zhttps://apollozhu.github.io/en/2017/08/23/github-swift-style-guide-irony/GitHub's Swift Style Guide<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><p>When I was cleaning up my GitHub repos and stars, I found <a href="https://github.com/github/swift-style-guide">GitHub’s style guide for Swift</a>, and I find this 2nd most starred style guide quite amusing.</p>
<span id="more"></span>
<p>Despite the fact that Xcode defaults to using 4 spaces for indentation (and we can clearly see the impact by checking <a href="https://ukupat.github.io/tabs-or-spaces/">tabs-or-spaces</a>), the style guide suggests using tabs instead. I’m totally fine with that, but I can easily tell there are some disagreements among the contributors:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myGreatProperty: <span class="type">Int</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">4</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">subscript</span>(<span class="params">index</span>: <span class="type">Int</span>) -> <span class="type">T</span> {</span><br><span class="line"> <span class="keyword">return</span> objects[index]</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>But there’s more. For now (2017 Auguest 23), there are three <a href="https://github.com/github?language=swift">Swift repos</a> under GitHub’s <a href="https://github.com/github">main account</a> – one source, two forks. Well, then let’s focus on <a href="https://github.com/github/SoftU2F">SoftU2F</a>, the ONLY Swift repository GitHub actually owns. Isn’t it natural for me to expect this repo to follow GitHub’s own style guide? But ironically, even SoftU2F is <em><strong>NOT</strong></em> doing that!</p>
<p><img src="https://octodex.github.com/images/front-end-conftocat.png" alt="The Front-End Conftocat on GitHub Octoex" /></p>
<p>In conclusion, seems that GitHub is not interested in styling their Swift code, and thus the GitHub community (or at least the 4k stargazers) has no actual intention to follow GitHub’s style guide, too.</p>
2017-08-23T21:02:25.000Zhttps://apollozhu.github.io/en/2017/07/17/fhana-hello-my-world/Hello!My World!! - fhána<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Map<Creation> hello = <span class="comment">/*my*/</span> <span class="keyword">new</span> <span class="title class_">World</span>();</span><br><span class="line"><span class="comment">// The Java I learned might be a fake one.</span></span><br></pre></td></tr></table></figure>
<div id="aplayer-uGoQgClO" class="aplayer aplayer-tag-marker meting-tag-marker"
data-id="003fWrVi0rKCtE" data-server="tencent" data-type="song" data-mode="circulation" data-autoplay="false" data-mutex="true" data-listmaxheight="340px" data-preload="auto" data-theme="#66ccff"
></div>
2017-07-17T14:35:00.000Zhttps://apollozhu.github.io/en/2017/05/24/letter-to-apcsa-students/A "Good" Letter to Next Years' APCSA Students<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><blockquote>
<p>This letter was included into the <a href="https://drive.google.com/file/d/0BzsLc9xUiW_Oajh6cUNGVXJZUms/view">summer packet</a> with minor modifications</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (Student student : APCSA.future.students)</span><br><span class="line"> System.out.print(<span class="string">"Hello "</span>+ student.name);</span><br></pre></td></tr></table></figure>
<p>You’ll learn about computer science and Java here. You won’t be learning about how to write visually attractive programs for the most of the times, but what you learn will empower you to write those programs with ease. This course is the prerequisites for all other CS courses, but why are you taking it? For me, <strong>I was here to learn.</strong></p>
<span id="more"></span>
<p>Despite the fact that I love programming, I’m afraid of computer science, especially those abstract algorithms. To prepare for this course, I read Think Java carefully. Mr. Lau suggested to read the first three chapters, I read it entirely. You can download it on your phone, and read it whenever you take your phone out. You don’t need a full time period, except for the exercises at the end of each chapter. You might find yourself unable to complete the exercise questions like me; if you do, just go back and read about that part again. There are no preferred answers to those questions, so any code that generates the same result are correct. But if you ever wonder, mine is on <a href="https://github.com/ApolloZhu/Think-Java-Exercises">GitHub</a>.</p>
<p>Even with a significant amount of knowledge about programming, you can always find something new here, so don’t just assume you are omniscient. Java is advanced but primitive, stern but nonchalant, expressive yet confusing. Learning Java is like learning a foreign language, you have to practice using it. Thus, I strongly recommend starting the labs early. Similar to those exercises included in Think Java, there are no standard ways to implement them. Therefore, explain to your tutor how you choose to complete the task, don’t let them type the code for you. And you never want your friend to show you their program; it will limit your imagination.</p>
<p>This course requires you to think logically, trace what’s going on. It is a frustrating process, but the good news is, you have a lot of resources. You can ask questions in class, take notes on or annotate important concepts for review. Another option is coming to Mr. Lau’s cougar time. You’ll find a comfortable environment for studying computer science. If you have any questions, you can always ask Mr. Lau or students around you. A lot of “good” students and center tutors come on daily bases. They will always help you <em><strong>IFF</strong></em> you ask. Or join Oakton Computer Science Club, you’ll find many opportunities to practice what you learned in this course, and meet with some really advanced students.</p>
<p>You can be a good student too. It’s very simple: <strong>understand what you are doing.</strong> <em><strong>Never use a code snippet until you can write it and its variations out without any assistance.</strong></em> I’m definitely talking about plagiarism, but that’s not my focus. I want to emphasis on the importance of solving problems by yourself. If you can’t visualize the process in your head, draw a graph, a table, or a stack to visualize the flow of your program. If your program doesn’t compile, read the error messages. A lot of them doesn’t make any sense to you (and me), but you’ll find the culprit through these traces. If you have a logic error, try break points. They are very easy to learn and convenient to use. You’ll find them handy.</p>
<p>Other than understanding how it works, <strong>you need to know why it works.</strong> You can achieve this by reading the source code of Java. Written by top developers in the world, Java source code demonstrates the conventions of writing Java code. You can compare your own solutions to theirs, and ask yourself what’s the difference. With a lot of documentations and comments, you can figure out why they choose to do it that way. Of course I’m not asking you to read all 2 billion lines of Java code, that’s neither necessary nor efficient. When Mr. Lau tell you “this is not natural,” it is a good place to start. If you have a professional IDE like Eclipse, just ctrl/command click on that method or class; otherwise, find it in the <code>JAVA_HOME</code> directory.</p>
<p>A quick note for those “good” students. You may use “advanced” stuff – such as regular expressions and lambdas – in your lab. That’s what people use in real life, but make sure you know how to complete the tasks without those language features, fancy methods, and classes.</p>
<p>Remember: <em><strong>ALL</strong></em> are equal before computer science; <code>(to be) || !(to be)</code>, that is <code>true</code>.</p>
<p><a href="https://github.com/ApolloZhu">@ApolloZhu</a><br />
2017/5/24</p>
2017-05-24T23:59:59.000Zhttps://apollozhu.github.io/en/2017/05/02/apcsa-appendix-b/Exam Appendix -- Java Quick Reference<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><p>Accessible methods from the Java library that may be included on the exam</p>
<span id="more"></span>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">java</span>.lang.Object {</span><br><span class="line"> <span class="type">boolean</span> <span class="title function_">equals</span><span class="params">(Object other)</span>;</span><br><span class="line"> String <span class="title function_">toString</span><span class="params">()</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">java</span>.lang.Integer {</span><br><span class="line"> Integer(<span class="type">int</span> value);</span><br><span class="line"> <span class="type">int</span> <span class="title function_">intValue</span><span class="params">()</span>;</span><br><span class="line"> <span class="comment">/** Minimum value represented by an `int` or `Integer`. */</span></span><br><span class="line"> <span class="keyword">static</span> <span class="type">int</span> MIN_VALUE;</span><br><span class="line"> <span class="comment">/** Maximum value represented by an `int` or `Integer`. */</span></span><br><span class="line"> <span class="keyword">static</span> <span class="type">int</span> MAX_VALUE;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">java</span>.lang.Double {</span><br><span class="line"> Double(<span class="type">double</span> value);</span><br><span class="line"> <span class="type">double</span> <span class="title function_">doubleValue</span><span class="params">()</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">java</span>.lang.String <span class="keyword">implements</span> <span class="title class_">java</span>.lang.Comparable<String> {</span><br><span class="line"> <span class="type">int</span> <span class="title function_">length</span><span class="params">()</span>;</span><br><span class="line"> <span class="comment">/** <span class="doctag">@return</span> the substring beginning at `from` and ending at `to-1`. Note: the substring has length of `to - from`. */</span></span><br><span class="line"> String <span class="title function_">substring</span><span class="params">(<span class="type">int</span> from, <span class="type">int</span> to)</span>;</span><br><span class="line"> <span class="comment">/** <span class="doctag">@return</span> `substring(from, length())`. */</span></span><br><span class="line"> String <span class="title function_">substring</span><span class="params">(<span class="type">int</span> from)</span>;</span><br><span class="line"> <span class="comment">/** <span class="doctag">@return</span> the index of the first occurrence of `str`; -1 if not found. */</span></span><br><span class="line"> <span class="type">int</span> <span class="title function_">indexOf</span><span class="params">(String str)</span>;</span><br><span class="line"> <span class="comment">/** <span class="doctag">@return</span> value < 0 if `this` less than `other`; 0 if equals to `other`; > 0 if greater than `other`. Note: According to ACSII. */</span></span><br><span class="line"> <span class="type">int</span> <span class="title function_">compareTo</span><span class="params">(String other)</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">java</span>.lang.Math {</span><br><span class="line"> <span class="keyword">static</span> <span class="type">int</span> <span class="title function_">abs</span><span class="params">(<span class="type">int</span> x)</span>;</span><br><span class="line"> <span class="keyword">static</span> <span class="type">double</span> <span class="title function_">abs</span><span class="params">(<span class="type">double</span> x)</span>;</span><br><span class="line"> <span class="keyword">static</span> <span class="type">double</span> <span class="title function_">pow</span><span class="params">(<span class="type">double</span> base, <span class="type">double</span> exponent)</span>;</span><br><span class="line"> <span class="keyword">static</span> <span class="type">double</span> <span class="title function_">sqrt</span><span class="params">(<span class="type">double</span> x)</span>;</span><br><span class="line"> <span class="keyword">static</span> <span class="type">double</span> <span class="title function_">random</span><span class="params">()</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">interface</span> <span class="title class_">java</span>.util.List<E> {</span><br><span class="line"> <span class="type">int</span> <span class="title function_">size</span><span class="params">()</span>;</span><br><span class="line"> <span class="comment">/** Appends obj to end of list. <span class="doctag">@return</span> `true` Note: only if operation allowed, such as always true for `ArrayList`. */</span></span><br><span class="line"> <span class="type">boolean</span> <span class="title function_">add</span><span class="params">(E obj)</span>;</span><br><span class="line"> <span class="comment">/** Inserts `obj` at position `index`, for 0 ≤ `index` ≤ `size()`. */</span></span><br><span class="line"> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">(<span class="type">int</span> index, E obj)</span></span><br><span class="line"> E <span class="title function_">get</span><span class="params">(<span class="type">int</span> index)</span>;</span><br><span class="line"> <span class="comment">/** Replaces the element at position `index` with `obj`. <span class="doctag">@return</span> the element formerly at the specified position. */</span></span><br><span class="line"> E <span class="title function_">set</span><span class="params">(<span class="type">int</span> index, E obj)</span>;</span><br><span class="line"> <span class="comment">/** Removes element from position `index`, moving elements at position `index + 1` and higher to the left by 1 (subtracts 1 from their indices) and adjusts size. <span class="doctag">@return</span> the element formerly at the specified position. */</span></span><br><span class="line"> E <span class="title function_">remove</span><span class="params">(<span class="type">int</span> index)</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">java</span>.util.ArrayList<E> <span class="keyword">implements</span> <span class="title class_">java</span>.util.List<E> { }</span><br></pre></td></tr></table></figure>
2017-05-02T01:05:54.000Zhttps://apollozhu.github.io/en/2017/03/24/bloody-blood/Near & Blood<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><blockquote><p>The near in blood, the nearer bloody.</p>
<footer><strong>William Shakespeare</strong><cite>Macbeth</cite></footer></blockquote>
2017-03-24T10:05:39.000Zhttps://apollozhu.github.io/en/2017/03/24/daggers-in-smiles/Daggers in Smiles<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/en/assets/css/APlayer.min.css"><script src="/en/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/en/assets/js/Meting.min.js"></script><blockquote><p>There’s daggers in men’s smiles.</p>
<footer><strong>William Shakespeare</strong><cite>Macbeth</cite></footer></blockquote>
2017-03-24T10:05:08.000Z