<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Philosophy on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/philosophy/</link><description>Recent content in Philosophy on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Fri, 27 Jan 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/philosophy/index.xml" rel="self" type="application/rss+xml"/><item><title>Using the Community</title><link>https://blog.iankulin.com/using-the-community/</link><pubDate>Fri, 27 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/using-the-community/</guid><description>&lt;p&gt;You can&amp;rsquo;t always successfully google problems when you&amp;rsquo;re starting out - usually because you don&amp;rsquo;t know the correct terminology for the issue or solution. Often you might still get a newbie StackOverflow hit, but when there&amp;rsquo;s not even that, you need a human to help out.&lt;/p&gt;
&lt;p&gt;One of the things &lt;a href="https://zerotomastery.io/"&gt;ZTM&lt;/a&gt; do with their courses is to have a Discord based community, then set tasks to encourage it&amp;rsquo;s use - for example one of the exercises I&amp;rsquo;ve already had was to go there and answer a question. Earlier ones were to introduce yourself and to find a partner to work with - both of which would have forced anyone not used to Discord to figure it out.&lt;/p&gt;
&lt;p&gt;As always when interacting with a community to get help, you need to have done your homework, and to have taken care to supply enough context that someone actually can answer it.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-01-18-at-4.43.55-pm.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the CodePen of exactly centering an image on a div.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://codepen.io/IanKulin/pen/rNrGREy"&gt;View embed&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Curse of Backwards Compatibility</title><link>https://blog.iankulin.com/curse-of-backwards-compatibility/</link><pubDate>Thu, 29 Dec 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/curse-of-backwards-compatibility/</guid><description>&lt;p&gt;I was listening to a JavaScript podcast today (&lt;a href="https://www.youtube.com/watch?v=O0fvMJcca3A"&gt;JavaScript Jabber&lt;/a&gt;) and in one of the discussions a point was made about how HTML, CSS and JavaScript have all had to maintain considerable legacy behaviors that compile-able languages do not have to. For instance, when Swift underwent some substantial changes from Swift 2 to Swift 3 - some code broke for developers and needed reworking because things had changed or been removed. Nothing broke for users - they could either still use their previously compiled applications, or they were delivered new ones from the app store.&lt;/p&gt;
&lt;p&gt;In web world - that&amp;rsquo;s not possible.&lt;/p&gt;
&lt;p&gt;Modern browsers need to be able to correctly render HTML from the birth of the web. I have a commercial site I last updated in 1996 that uses tables for some layout - it works fine in a modern browser.&lt;/p&gt;
&lt;p&gt;Having to bring forward all this functionality is great for web users (and people who don&amp;rsquo;t maintain their websites, but it weighs down the languages and makes learning them more difficult. This is related to my dilemma about ignoring block model and flex-box; in a compiled language they could have been deprecated in favour of grids, but in CSS they need to exist forever.&lt;/p&gt;
&lt;p&gt;This same theme was revisited in a &lt;a href="https://topenddevs.com/podcasts/javascript-jabber/episodes/jsj-421-semantic-html-with-bruce-lawson"&gt;later episode of the same podcast&lt;/a&gt;, this time in relation to semantic HTML and it&amp;rsquo;s benefits. The hosts wished that some improvements to web technologies &lt;em&gt;would&lt;/em&gt; break web-sites so people would be forced to update them.&lt;/p&gt;</description></item><item><title>Clean code</title><link>https://blog.iankulin.com/clean-code/</link><pubDate>Fri, 09 Dec 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/clean-code/</guid><description>&lt;p&gt;I&amp;rsquo;ve been listening to the &lt;a href="https://www.youtube.com/watch?v=YVrHPCZnC50"&gt;latest episode of the Empower Apps&lt;/a&gt; podcast, this one with &lt;a href="https://twitter.com/Jilsco9"&gt;Jill Scott&lt;/a&gt; talking about &amp;ldquo;Humane&amp;rdquo; development - in the sense of being humane to whoever (probably you) is going to be reading this code in the future. It helped me clarify my thoughts about a couple of things.&lt;/p&gt;
&lt;p&gt;None of these ideas are particularly new or groundbreaking, and although I think of them as my personal style, they are very common, and in Swift could be regarded as part of the culture. Some of these concepts support each other, some represent a trade off between two opposing ideas that require us to make a choice.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/onion-belt.jpg" alt=""&gt;&lt;/p&gt;
&lt;h4 id="the-custom-at-the-time"&gt;The Custom at the Time&lt;/h4&gt;
&lt;p&gt;If other people or bots are going to read your code, or you need to comprehend theirs, there is a lot of value in following the conventions in the language of community you work in. It helps in a couple of ways - 1) you are not expending energy deciding if equals signs should have a space each side, and 2) fluency of reading and writing will improve.&lt;/p&gt;
&lt;h4 id="natural-language"&gt;Natural Language&lt;/h4&gt;
&lt;p&gt;If it&amp;rsquo;s possible to make choices in a piece of code to make it read more like a description of what is happening, then usually do that. Swift (and probably other modern languages - I wouldn&amp;rsquo;t know) has some great language features to support this. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;answer = resultOf(6, plus: 7)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I also appreciate the Swift convention of using auxiliary verbs. I think &lt;code&gt;isPaused&lt;/code&gt; or &lt;code&gt;hasCompleted&lt;/code&gt; is clearer that &lt;code&gt;paused&lt;/code&gt; or &lt;code&gt;completed&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id="decomposed"&gt;Decomposed&lt;/h4&gt;
&lt;p&gt;There&amp;rsquo;s probably a reason why paragraphs exist in writing, and are about the length they usually are, deep in the science of how memory works in humans and the interplay between working memory and what else goes on in comprehending something.&lt;/p&gt;
&lt;p&gt;I start to get uncomfortable if a chunk of code I&amp;rsquo;m trying to understand or write is more than a couple of 13&amp;quot; laptop screens long. I thought &lt;a href="https://davidstechtips.com/2012/05/folding-code-in-xcode/comment-page-1/"&gt;code folding&lt;/a&gt; would help but haven&amp;rsquo;t really found that. I aim to have each chunk (I&amp;rsquo;m using &amp;ldquo;chunk&amp;rdquo; for function, method, computed property etc) express a single idea. If part of it is getting long, I consider if that can be removed somewhere else and replaced with a helpful function name in the piece I&amp;rsquo;m working on.&lt;/p&gt;
&lt;h4 id="less-magic"&gt;Less Magic&lt;/h4&gt;
&lt;p&gt;When I&amp;rsquo;m working with some code, I don&amp;rsquo;t want it to need too much context to understand. This principle means anything used in this code should come in through the obvious interface. Global variables, environment variables, or stuff captured from the enclosing scope are undesirable. If I use them, I try and put them near the top since that&amp;rsquo;s where people (me) look when they encounter something part way through the code and don&amp;rsquo;t know where it came from.&lt;/p&gt;
&lt;p&gt;In an ideal world, I could grab a piece of code and paste it into a &lt;a href="https://gist.github.com/discover"&gt;gist&lt;/a&gt; to share here and it would be comprehensible.&lt;/p&gt;
&lt;h4 id="evaporated-comments"&gt;Evaporated Comments&lt;/h4&gt;
&lt;p&gt;I doubt I invented this, but I haven&amp;rsquo;t seen it mentioned anywhere else either. The way I most commonly use comments is to clarify my thoughts before I write any code, something like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;func&lt;/span&gt; sendFile&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;fileName&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#bf616a"&gt;String&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; link&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; NetworkTube&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;-&amp;gt;&lt;/span&gt; SendResultCode &lt;span style="color:#eceff4"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; check link is operational
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; attempt to open file
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; step through each line sending it&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; wait &lt;span style="color:#81a1c1;font-weight:bold"&gt;for&lt;/span&gt; ack 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; close file
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;return&lt;/span&gt; code
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then as I flesh out the function, I delete the comment if the code is straight forward. Usually this results in all of the comments being deleted. In my Swift code, comments are quite rare. Where there are comments, it&amp;rsquo;s probably a sign I need to name things better.&lt;/p&gt;
&lt;p&gt;I just went back through the code for that apps I actually use on my phone, and these are the only comments I could find outside of a header.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;var&lt;/span&gt; fractionDue&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; Double &lt;span style="color:#eceff4"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; when a habit is overdue&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;or&lt;/span&gt; due now&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; the fractionDue is &lt;span style="color:#b48ead"&gt;1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; when it&lt;span style="color:#a3be8c"&gt;&amp;#39;s not due at all - just been done, the fractioDue is 0.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;if&lt;/span&gt; isDueNow &lt;span style="color:#eceff4"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;return&lt;/span&gt; &lt;span style="color:#b48ead"&gt;1.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;else&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; let daysSinceDone &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; Date&lt;span style="color:#eceff4"&gt;()&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;timeIntervalSince&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;lastDone&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;/&lt;/span&gt; &lt;span style="color:#b48ead"&gt;86&lt;/span&gt;_400
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1"&gt;assert&lt;/span&gt;&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;daysBetweenCompletions &lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#b48ead"&gt;0.0&lt;/span&gt;&lt;span style="color:#eceff4"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;return&lt;/span&gt; daysSinceDone &lt;span style="color:#81a1c1"&gt;/&lt;/span&gt; daysBetweenCompletions
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a computed variable in a &amp;ldquo;Habit&amp;rdquo; struct. I wanted to have little ticks next to each habit when they were done, which would slowly fade to be completely gone when this habit was due again. To achieve this I needed to calculate an opacity value for the tick. I think it&amp;rsquo;s fair to say this needs re-working. I don&amp;rsquo;t recall if I wrote the comment first, or put it there later recognising the code wasn&amp;rsquo;t self explanatory - it could have been either.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not sure I could fix this to the point it wouldn&amp;rsquo;t need a comment at all. There&amp;rsquo;s a couple of name changes that would help. I think &lt;code&gt;daysSinceDone&lt;/code&gt; would be better as &lt;code&gt;daysSinceLastCompleted&lt;/code&gt;, and instead of calling the property &lt;code&gt;fractionDue&lt;/code&gt;, I might call it &lt;code&gt;freshness&lt;/code&gt;. Instead of dividing the time interval by 86,400 I could have a &lt;code&gt;millisecondsToDays()&lt;/code&gt;function.&lt;/p&gt;</description></item><item><title>List Apps</title><link>https://blog.iankulin.com/list-apps/</link><pubDate>Thu, 20 Oct 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/list-apps/</guid><description>&lt;p&gt;When I was first programming professionally, it wasn&amp;rsquo;t long before I noticed that there were patterns to the sort of bread-and-butter things I was writing most times - the majority of the small business applications I wrote tracked several entities; for each entity there needed to be add/edit/delete screens, there would be some business rules around those things, and some reports and search functionality.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://www.hackingwithswift.com/guide/ios-swiftui/4/3/challenge"&gt;Day 47 Milestone app&lt;/a&gt; is for tracking habits - presented in a list; you need to be able to add and delete them, view details and do some business logic on them. Not only does this sound a lot like the earlier expense tracking app, but also not that different to the app idea I&amp;rsquo;ve got for tracking when I charge each of the rechargeable batteries in my house.&lt;/p&gt;
&lt;p&gt;Eventually these list type apps written in SwiftUI will need a better (perhaps MVVM) architecture, but at the simple end, it seems these apps are going to be some variation on this recipe:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The item is going to be a struct with an id&lt;/li&gt;
&lt;li&gt;It will conform to Identifiable and Codable&lt;/li&gt;
&lt;li&gt;The collection of items will be a class that inherits from ObservableObject&lt;/li&gt;
&lt;li&gt;The collection property will be @Published&lt;/li&gt;
&lt;li&gt;The collection property will have an init() that reads the items from somewhere and a didset() that writes them&lt;/li&gt;
&lt;li&gt;The instance of that collection class will be an @StateObject&lt;/li&gt;
&lt;li&gt;The items will be shown as a List inside a NavigationView&lt;/li&gt;
&lt;li&gt;It will probably have a toolbar with a control to add items&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Patterns in development like this are convenient - they lead to high quality programs developed quickly, and being compliant with the &lt;a href="https://developer.apple.com/design/human-interface-guidelines/guidelines/overview/"&gt;Apple HIG&lt;/a&gt; means all the behaviours will be familiar to users as well as being accessible.&lt;/p&gt;
&lt;p&gt;The danger is that they look and feel like every other list type app, so developers need to think carefully about what all the common use cases are, as well as appealing design, to ensure the users&amp;rsquo; needs are being addressed and the application can justify it&amp;rsquo;s existence alongside all the other offerings.&lt;/p&gt;</description></item></channel></rss>