Jekyll2023-01-04T00:24:37+00:00https://iandickinson.me.uk/blog/blog/feed.xmlReactive, autonomousThe blog of Ian DickinsonIan Dickinsonian@iandickinson.me.ukWeek notes: 30 Oct 20212021-10-30T00:00:00+01:002021-10-30T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-10-30/week-notes-30-oct-2021<p>Some notes of things I’ve been reading about recently:</p>
<ul>
<li>Interesting read on what a modern
<a href="https://benn.substack.com/p/the-modern-data-experience">data experience should be like</a></li>
<li>One method for creating a <a href="https://designmodo.com/vertical-rhythm/">vertical rhythm in CSS</a></li>
<li>I’ve not really played with this yet, but it looks interesting:
<a href="https://docs.datasette.io/en/stable/">Datasette data exploration tool (Python)</a></li>
<li>Automatically <a href="https://www.npmjs.com/package/ts-transformer-dates">transforming JSON date strings to <code class="language-plaintext highlighter-rouge">Date</code>s</a>
in TypeScript. In theory this should work well, since the <code class="language-plaintext highlighter-rouge">ts</code> compiler knows which fields in
an <code class="language-plaintext highlighter-rouge">interface</code> have type <code class="language-plaintext highlighter-rouge">Date</code>, and so can transform JSON input automagically. However,
this method relies on TypeScript custom transforms, and I couldn’t get it to work. But maybe
future-TypeScript will make this easier to configure.</li>
<li>Very comprehensive graph library for JavaScript: <a href="https://js.cytoscape.org/">Cytoscape</a></li>
</ul>Ian Dickinsonian@iandickinson.me.ukSome notes of things I’ve been reading about recently:Week notes: 13 Oct 20212021-10-13T00:00:00+01:002021-10-13T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-10-13/week-notes-13-oct-2021<p>Once again, it’s been a while since I last updated my list of interesting things I’ve
been reading about. And I’ve been in hospital briefly for a scheduled op, which means
that I am in a recovery period now, but has given me a little bit more time for
catching up on my list.</p>
<ul>
<li>I finished Prof. Melanie Mitchell’s <a href="https://melaniemitchell.me/aibook/">Artificial Intelligence - A Guide for Thinking Humans</a>
If you’re struck by the punniness of the title, and think that it sounds a bit Douglas Hofstadter,
that’s not a coincidence. Prof Mitchell was a PhD student in Hofstadter’s research group, having
first fallen in love with <a href="https://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach">Gödel, Escher, Bach</a>
(didn’t we all? I certainly did). But this book, while it touches on analogies and reasoning a
bit, is mostly a lively overview of the current state of deep learning, and why it’s going to be
hard for DL systems to transcend their task-centric boundaries to achieve generalised intelligence.
I really enjoyed the book, and wholeheartedly recommend it.</li>
<li>I know a <strong>lot</strong> of programming languages, but I haven’t built that many full-scale Python apps.
So I want to know a bit more about how to write really good Python code. That’s ostensibly the
premise of Dmitry Zinoviev’s <a href="https://pragprog.com/titles/dzpythonic/pythonic-programming/">Pythonic Programming</a>.
It was … OK, but it’s no <a href="http://eloquentruby.com/">Eloquent Ruby</a> or <a href="https://store.avdi.codes/l/rrWapR">Confident Ruby</a>.
Those books try hard to instil the actual principles of good Ruby code, whereas Zinoviev’s book is
a collection of 100 tips that attempt to convey something of what constitutes the Pythonic
way. It’s not bad, and I certainly did learn some things. But I also found myself wanting
something a little more principled. And I’m afraid I do disagree with a small number of the tips!</li>
<li>I enjoyed hearing <a href="https://mjwhansen.com/">Michele Hansen</a> on the
<a href="https://www.indiehackers.com/podcast/224-michele-hansen">IndieHackers podcast</a>, so I bought a copy
of her book <a href="https://mjwhansen.com/deploy-empathy/">Deploy Empathy</a>. It’s a collection of tips
and suggestions for doing better customer research during product development. I’m only part-way
through so far, but enjoying it.</li>
</ul>Ian Dickinsonian@iandickinson.me.ukOnce again, it’s been a while since I last updated my list of interesting things I’ve been reading about. And I’ve been in hospital briefly for a scheduled op, which means that I am in a recovery period now, but has given me a little bit more time for catching up on my list.Week notes: 10 Sept 20212021-09-10T00:00:00+01:002021-09-10T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-09-10/week-notes-10-sept-2021<p>An overdue list of a few of the things I’ve been reading about recently:</p>
<ul>
<li>output from <a href="https://www.ipcc.ch/report/ar6/wg1/">Working Group 1 of the AR6 Climate Change report</a>.
I don’t know what to say about this, except that it’s scary AF.</li>
<li>interesting <a href="https://dev.to/richharris/stay-alert-d">article</a>
(including the comments thread) on the forthcoming
demise of <code class="language-plaintext highlighter-rouge">alert()</code> from cross-site iFrames in Chrome.</li>
<li><a href="https://blog.vuejs.org/posts/vue-3.2.html">release 3.2 of Vue</a> has some
nice features and performance upgrades</li>
<li>a jobs board focussing on <a href="https://climatebase.org/">jobs in helping to address climate change</a></li>
</ul>Ian Dickinsonian@iandickinson.me.ukAn overdue list of a few of the things I’ve been reading about recently:Week notes: 11 Aug, 20212021-08-11T00:00:00+01:002021-08-11T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-08-11/week-notes-11-aug-2021<p>I’m rather late putting this collection of week-notes out. No excuses, I just
got pulled onto other things. Anyway, some of the things that have caught my
attention recently:</p>
<ul>
<li>good news: there’s going to be a
season 2 of <a href="https://www.youtube.com/watch?v=wPm7K0xpR0A">Good Omens</a></li>
<li><a href="https://www.quantamagazine.org/melanie-mitchell-trains-ai-to-think-with-analogies-20210714">interview with Melanie Mitchell</a>.
<br />
I first came across <a href="(https://melaniemitchell.me/)">Prof. Mitchell</a>
on the <a href="https://twimlai.com/complexity-and-intelligence-with-melanie-mitchell/">TWiML AI podcast</a>,
and enjoyed that so much I bought her
<a href="https://www.hive.co.uk/Product/Melanie-Mitchell/Artificial-Intelligence--A-Guide-for-Thinking-Humans/24737879">book</a>.</li>
<li>Some handy notes on <a href="https://www.smashingmagazine.com/2021/07/frontend-testing-pitfalls/">front-end testing</a></li>
<li>great collection of <a href="https://dev.to/michaelthiessen/25-vue-tips-you-need-to-know-2h70">Vue tips</a></li>
</ul>Ian Dickinsonian@iandickinson.me.ukI’m rather late putting this collection of week-notes out. No excuses, I just got pulled onto other things. Anyway, some of the things that have caught my attention recently:Vue3 composition API style tip2021-08-08T00:00:00+01:002021-08-08T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-08-08/vue3-composition-api-style-tip<p>I have a couple of new projects on the go, and I really want to try out the
composition API for Vue3. I’ve seen a few examples on-line, and they emphasise
using the <code class="language-plaintext highlighter-rouge">setup</code> method to create <code class="language-plaintext highlighter-rouge">ref</code>s and <code class="language-plaintext highlighter-rouge">computed</code>s using the
composition API functions. And they all end up with all that code in one
giant <code class="language-plaintext highlighter-rouge">setup</code> function. At which point, I imagine that scaled-up to a full
application, and find myself thinking “Surely, you can’t be serious?”</p>
<p><img src="https://c.tenor.com/S4frNyKAkFYAAAAC/surely-you-cant-be-serious-i-am-serious-and-dont-call-me-shirley.gif" alt="Surely you can't be serious GIF from the movie Airplane" /></p>
<p>The <a href="https://v3.vuejs.org/style-guide/#rule-categories">Vue3 style guide</a> doesn’t
offer any suggestions, and searching online for composition API style guide or
tips wasn’t very fruitful.</p>
<p>However, it turns out that the Vue3 docs do directly address this concern:</p>
<blockquote>
<p>We could do the same for other <strong>logical concerns</strong> but you might be already
asking the question –
<em>Isn’t this just moving the code to the setup option
and making it extremely big?</em>
Well, that’s true. That’s why before moving
on with the other responsibilities, we will first extract the above code
into a standalone <strong>composition function</strong>.</p>
</blockquote>
<p><a href="https://v3.vuejs.org/guide/composition-api-introduction.html#standalone-computed-properties">source</a></p>
<p>The recommendation goes on to suggest creating a <code class="language-plaintext highlighter-rouge">composables</code> directory, from
which we can import these logical-features into a component’s <code class="language-plaintext highlighter-rouge">setup</code> function:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// src/components/UserRepositories.vue</span>
<span class="k">import</span> <span class="nx">useUserRepositories</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@/composables/useUserRepositories</span><span class="dl">'</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">toRefs</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">vue</span><span class="dl">'</span>
<span class="k">export</span> <span class="k">default</span> <span class="p">{</span>
<span class="na">components</span><span class="p">:</span> <span class="p">{</span> <span class="nx">RepositoriesFilters</span><span class="p">,</span> <span class="nx">RepositoriesSortBy</span><span class="p">,</span> <span class="nx">RepositoriesList</span> <span class="p">},</span>
<span class="na">props</span><span class="p">:</span> <span class="p">{</span>
<span class="p">...</span>
<span class="p">},</span>
<span class="nx">setup</span> <span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">const</span> <span class="p">{</span> <span class="nx">user</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">toRefs</span><span class="p">(</span><span class="nx">props</span><span class="p">)</span>
<span class="kd">const</span> <span class="p">{</span> <span class="nx">repositories</span><span class="p">,</span> <span class="nx">getUserRepositories</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">useUserRepositories</span><span class="p">(</span><span class="nx">user</span><span class="p">)</span>
</code></pre></div></div>
<p>I think there will be much more to say on creating good patterbs for structuring
composition-API Vue3 components, but for now I just wanted to add some search-juice
for this suggestion for a style-guide for Vue3 components using the composition API.</p>Ian Dickinsonian@iandickinson.me.ukI have a couple of new projects on the go, and I really want to try out the composition API for Vue3. I’ve seen a few examples on-line, and they emphasise using the setup method to create refs and computeds using the composition API functions. And they all end up with all that code in one giant setup function. At which point, I imagine that scaled-up to a full application, and find myself thinking “Surely, you can’t be serious?”RDF, Typescript and Deno - Part 3b2021-08-03T00:00:00+01:002021-08-03T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-08-03/rdf-typescript-and-deno-part-3b<p>One of my all-time favourite programming languages is Prolog. In
Prolog terms, my investigation of RDF, Typescript and Deno has
reached this step:</p>
<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="p">!,</span>
<span class="ss">fail</span><span class="p">.</span>
</code></pre></div></div>
<p>“Cut, fail” indicates to the Prolog interpreter to stop exploring this branch
of the evaluation tree, and go back to a previous choice point to try a
different path. It won’t cause the program to halt altogether (unless the
program has run out of choices to make), but will make it back up to a
previously non-cut choice point.</p>
<p>So to make this relevant to the topic at hand (finally!): I’m giving
up on Deno as vehicle for exploring the JavaScript <code class="language-plaintext highlighter-rouge">rdflib</code> package.
Deno is, for certain purposes, great. rdflib is, for certain purposes,
great. They just don’t play nice together.</p>
<p>Some of the issues I ran into included:</p>
<ul>
<li>
<p>rdflib uses <code class="language-plaintext highlighter-rouge">import</code> statements that import relative modules. I
actually <a href="https://stackoverflow.com/questions/68552759/deno-unable-to-import-a-library-which-contains-relative-imports">asked about this on StackOverflow</a>.
Deno likes fully-qualified module specifiers. Tbh, I don’t fully
understand the details of the explanation, but suffice to say
that I couldn’t get the suggested fix to work.</p>
</li>
<li>
<p>importing types with the <code class="language-plaintext highlighter-rouge">@deno-types="..."</code> annotation I also
couldn’t get to work, so VsCode wasn’t able to typecheck my Typescript
code. This even though rdflib has <code class="language-plaintext highlighter-rouge">.ts</code> source files</p>
</li>
<li>
<p>some rdflib imports use Node packages that Deno doesn’t support
yet, including <code class="language-plaintext highlighter-rouge">https</code>.</p>
</li>
</ul>
<h2 id="what-i-did-like">What I did like</h2>
<p>There are definitely things to like about Deno. It’s fast. It’s nicely
optimised for running small scripts effectively: I would imagine that
it’s a perfect vehicle for AWS Lambda functions, for example. When the
type checking is working (see above), it works well in VsCode. It’s nice
not having to start a project with a load of <code class="language-plaintext highlighter-rouge">package.json</code> wrangling.
The security model is a good idea in principle, although I’d anticipate
adding <code class="language-plaintext highlighter-rouge">--allow-read</code>, <code class="language-plaintext highlighter-rouge">--allow-net</code>, etc, as reflexes without properly
thinking about it. The weakest part of any security protocol is the
humans!</p>
<p>For all of the good things above, I think (extrapolating from just one
data point: always a dubious idea!) that Deno isn’t going to be a good
choice for large NPM modules or libraries that were written firmly during
a “pick any runtime engine you like, as long as it’s Node” era. Which
means waiting for libraries to get updated or rewritten, or taken on
writing that functionality yourself. For something big and hairy like RDF
(and SPARQL, and JSON-LD, and etc etc) that’s a deal-breaker for most
teams and non-superhuman individuals.</p>
<h2 id="what-next">What next</h2>
<p>To ponder. I still have a desire to write an <code class="language-plaintext highlighter-rouge">rdflib</code> tutorial, because
there aren’t many good ones around. On the other hand, I’m not that
into writing in Node Express. Previous to this experiment with Deno,
my tools-of-choice for writing the server-side element of an app were
Ruby-on-Rails or Python Flask.</p>
<p>All-in-all, I’m glad I tried the experiment. And I might come back to
Deno in future, to see if the integration with larger NPM modules has
changed significantly.</p>
<p>I am not done with Deno (see what I did there? :))</p>Ian Dickinsonian@iandickinson.me.ukOne of my all-time favourite programming languages is Prolog. In Prolog terms, my investigation of RDF, Typescript and Deno has reached this step:RDF, Typescript and Deno - Part 3a: all ahead stop2021-07-18T00:00:00+01:002021-07-18T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-07-18/rdf-typescript-and-deno-part-3a-all-ahead-stop<blockquote>
<p>Believing I had supernatural powers<br />
I slammed into a brick wall<br />
<em>(Paul Simon - Gumboots)</em></p>
</blockquote>
<p>I had hoped to get Part 3 of this mini-series on RDF, Typescript and Deno
out by now. The concepts aren’t hard to explain, and the code isn’t that
complicated. But what has proved to be extremely complicated is getting
the NPM library <code class="language-plaintext highlighter-rouge">rdflib.js</code> to import into my code.</p>
<p>There are <a href="https://medium.com/samsung-internet-dev/using-node-modules-in-deno-2885600ed7a9">various ways</a>
to use NPM modules in a Deno app. I’ve tried various approaches. None
have worked so far, but the furthest I’ve got is:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// rdf-generation.ts</span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">Namespace</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">https://dev.jspm.io/npm:rdflib@2.2.7/esm</span><span class="dl">'</span>
</code></pre></div></div>
<p>But when I try to cache the import:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>deno <span class="nt">--unstable</span> cache rdf-generation.ts
Download https://dev.jspm.io/npm:rdflib@2.2.7/esm
Download https://dev.jspm.io/npm:rdflib@2.2.7/esm/fetcher.js
Download https://dev.jspm.io/npm:rdflib@2.2.7/esm/query-to-sparql.js
Download https://dev.jspm.io/npm:rdflib@2.2.7/esm/variable.js
<span class="o">[</span>... lots more downloads ...]
Download https://dev.jspm.io/npm:rdflib@2.2.7/esm/factories/factory-types.js
Check file:///home/ian/projects/personal/deno-experiments/rdf-generation.ts
error: TS2502 <span class="o">[</span>ERROR]: <span class="s1">'thisArg'</span> is referenced directly or indirectly <span class="k">in </span>its own <span class="nb">type </span>annotation.
<span class="nb">bind</span><T><span class="o">(</span>this: T, thisArg: ThisParameterType<T><span class="o">)</span>: OmitThisParameter<T><span class="p">;</span>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
at asset:///lib.es5.d.ts:350:22
</code></pre></div></div>
<p>I think I’m going to have to seek some help!</p>Ian Dickinsonian@iandickinson.me.ukBelieving I had supernatural powers I slammed into a brick wall (Paul Simon - Gumboots)RDF, Typescript and Deno - Part 2: sample data2021-07-12T00:00:00+01:002021-07-12T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-07-12/rdf-typescript-and-deno-part-2-sample-data<p>In <a href="/blog/2021-07-04/rdf-typescript-and-deno">part 1</a>,
I laid out some reasons for looking using RDF in Typescript
using Deno. In this installment, I’ll put together some quick sample data
before I start looking at RDF specifically.</p>
<p>Sample data is always a challenge. Real-world data is often large and messy,
or has inconvenient license terms. On the other hand, synthetic data tends
to hide the kinds of issues we have to deal with day-to-day in data processing.
Who needs another todo list app, really?</p>
<p>For this exercise, I’m using recent sightings of cetaceans around the coast of
the UK by the <a href="https://www.seawatchfoundation.org.uk/">Sea Watch Foundation</a>.
There is - as far as I can see - no explicit license on this data, but as it’s
reported by anyone and concerns wild animals in their natural habitat I’m going
to assume it’s OK to use this data for tutorial purposes. Obviously if I find
out otherwise, I’ll use a different dataset.</p>
<p>There’s a tool on the Sea Watch web site to list recent sightings. It looks
like this:</p>
<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Bottlenose dolphin (x6) - Portland Bill, Dorset at 08:00 on 1 Jul 2021 by Des and Shirley Peadon
Grey Seal (x11) - The Chick Island, Cornwall at 15:17 on 30 Jun 2021 by Newquay Sea Safaris Newquay Sea Safaris
Sunfish (x1) - Towan Headland, Cornwall at 14:53 on 30 Jun 2021 by Newquay Sea Safaris Newquay Sea Safaris
</code></pre></div></div>
<p>This is reasonably well structured data, to human eyes, but still needs a bit of
processing to get it into a form we can conveniently process. By inspection,
each sighting contains:</p>
<ul>
<li>a species name</li>
<li>a quantity (optional)</li>
<li>a location</li>
<li>a time (optional)</li>
<li>a date</li>
<li>a reporter, which could be one or more individuals, or an organisation</li>
</ul>
<p>There’s a bit of variability in this structure, so it would be convenient to have it
as a more structured format, such as JSON:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"species"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Bottlenose dolphin"</span><span class="p">,</span><span class="w">
</span><span class="nl">"quantity"</span><span class="p">:</span><span class="w"> </span><span class="mi">12</span><span class="p">,</span><span class="w">
</span><span class="nl">"location"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Portland Bill, Dorset"</span><span class="p">,</span><span class="w">
</span><span class="nl">"spotter"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Alan Hold"</span><span class="p">,</span><span class="w">
</span><span class="nl">"date"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2021-06-30T23:00:00.000Z"</span><span class="p">,</span><span class="w">
</span><span class="nl">"time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"09:15"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Mostly this is a case of splitting each line of data up in a robust way, but also
performing some basic data transformation. The <code class="language-plaintext highlighter-rouge">quantity</code> field is parsed as an
integer, not a string, and the <code class="language-plaintext highlighter-rouge">date</code> is parsed as a JavaScript <code class="language-plaintext highlighter-rouge">Date</code> object. I
decided to keep the <code class="language-plaintext highlighter-rouge">time</code> field separate, as only around half of the sightings
record the time. In theory we could do some data reconciliation to try to recognise
the location and the species, but the data is likely to be too noisy to be able
to do this robustly. So for now, just robustly parsing the strings is enough.</p>
<p>The code for this data conversion step is
<a href="https://github.com/ijdickinson/deno-experiments/blob/main/data-generation.ts">available on GitHub</a>.
It’s mostly fairly straightforward; perhaps the main notes (other than Typescript
and Deno, see below) is that the work of the recogniser is a rather large regex.
In JavaScript, regular expressions can capture segments of the input in groups,
and these <em>capture groups</em> can be given a name using the construct <code class="language-plaintext highlighter-rouge">(?<name>...)</code>.
Conveniently, these named groups are returned as a JavaScript object looking like
the JSON structure above, as long as the names of the fields and capture groups line
up.</p>
<h2 id="of-typescript">Of Typescript</h2>
<p>TypeScript uses <em>type inference</em> to determine, and then check, the types of variables
and parameters automatically where it can. In this simple program, type inference
was mostly sufficient. The main thing I need to add to make the type checking work
was to constrain the output of the regular expression matcher. As mentioned above, I
wanted the output of the regex match to be an object closely resembling my eventual
result. The <code class="language-plaintext highlighter-rouge">groups</code> field of the match result <strong>is</strong> an object, but Typescript needs
to have more information before it can check that usages of that object are legal. So
I defined an interface type <code class="language-plaintext highlighter-rouge">SightingsData</code>, which is the interim, not final, form of
a line from the sightings data file:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">SightingsData</span> <span class="p">{</span>
<span class="nl">species</span><span class="p">:</span> <span class="kr">string</span>
<span class="nx">quant</span><span class="p">?:</span> <span class="kr">string</span>
<span class="nx">location</span><span class="p">:</span> <span class="kr">string</span>
<span class="nx">date</span><span class="p">:</span> <span class="kr">string</span>
<span class="nx">time</span><span class="p">?:</span> <span class="kr">string</span>
<span class="nx">spotter</span><span class="p">:</span> <span class="kr">string</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Then we can tell the compiler that this will be the result type from parsing, and
us the <code class="language-plaintext highlighter-rouge">as</code> operator to coerce the result (note that <code class="language-plaintext highlighter-rouge">LINE_MATCHER</code> is just the large
regex):</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">parseLine</span><span class="p">(</span><span class="nx">line</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nx">SightingsData</span> <span class="o">|</span> <span class="kc">undefined</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">line</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">LINE_MATCHER</span><span class="p">)?.</span><span class="nx">groups</span> <span class="k">as</span> <span class="p">(</span><span class="nx">SightingsData</span> <span class="o">|</span> <span class="kc">undefined</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Since the match can fail, we need the optional chaining operator <code class="language-plaintext highlighter-rouge">?.</code>, so if the
left-hand expression evaluates to falsey the expression will evaluate to just that
value. And then since the result overall may be undefined, the return type needs
to be the type expression <code class="language-plaintext highlighter-rouge">SightingsData | undefined</code>.</p>
<p>Using VsCode as my editor, TypeScript can work out the rest of the types, and show
them on mouse hover. Here, for example, is the result of hovering on <code class="language-plaintext highlighter-rouge">function asData</code>:</p>
<p><img src="../images/typescript-type-annotation-popup.png" alt="Screenshot of VsCode showing TypeScript type annotation" /></p>
<h2 id="of-deno">Of Deno</h2>
<p>This simple script doesn’t get to exercise much of Deno, but does show a couple of
interesting aspects. First, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">promises</a> are used as the basis for every (potentially)
asynchronous operation, like writing or reading files. That means lots of <code class="language-plaintext highlighter-rouge">async / await</code>
statements, or <code class="language-plaintext highlighter-rouge">.then()</code> calls. No callback functions.</p>
<p>Second, imports can be loaded directly from a URL:</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">parse</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">https://deno.land/x/date_fns@v2.22.1/parse/index.js</span><span class="dl">'</span>
</code></pre></div></div>
<p>In a node.js script, this would have meant adding <code class="language-plaintext highlighter-rouge">date_fns</code> to the <code class="language-plaintext highlighter-rouge">package.json</code> file
dependencies, then <code class="language-plaintext highlighter-rouge">yarn install</code> or <code class="language-plaintext highlighter-rouge">npm install</code> to get the dependency cached into
<code class="language-plaintext highlighter-rouge">node_modules</code>. Deno can work this way (spoiler alert for part 3 of this blog series),
but by default doesn’t need to.</p>
<p>Not diving for <code class="language-plaintext highlighter-rouge">yarn add</code> from the command line did feel a bit weird, but I expect I will
get used to it. More of an issue, I think, will be keeping the versions consistent. If I
use <code class="language-plaintext highlighter-rouge">date_fns</code> from more than one file, and then I need to upgrade to version <code class="language-plaintext highlighter-rouge">2.22.2</code>,
it seems I’ll have to grep for every use of <code class="language-plaintext highlighter-rouge">date_fns@2.22.1</code>. That doesn’t seem very
DRY, but maybe there are working practices I’ve not got used to yet.</p>
<p>The third thing about Deno is that scripts don’t have permission to perform risky operations
by default. “Risky” in this context means things like: reading a file, writing a file,
writing to the network, etc. Running without the permission causes an error:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nv">$ </span>deno run data-generation.ts
Check file:///home/ian/projects/personal/deno-experiments/data-generation.ts
error: Uncaught <span class="o">(</span><span class="k">in </span>promise<span class="o">)</span> PermissionDenied: Requires <span class="nb">read </span>access to <span class="s2">"./sightings-data.txt"</span>, run again with the <span class="nt">--allow-read</span> flag
const sourceData <span class="o">=</span> await Deno.readTextFile<span class="o">(</span><span class="nb">source</span><span class="o">)</span>
^
at deno:core/core.js:86:46
at unwrapOpResult <span class="o">(</span>deno:core/core.js:106:13<span class="o">)</span>
at async open <span class="o">(</span>deno:runtime/js/40_files.js:46:17<span class="o">)</span>
at async Object.readTextFile <span class="o">(</span>deno:runtime/js/40_read_file.js:40:18<span class="o">)</span>
at async readLines <span class="o">(</span>file:///home/ian/projects/personal/deno-experiments/data-generation.ts:18:22<span class="o">)</span>
</code></pre></div></div>
<p>It’s a nice clear error. But I found it quite easy to forget to add the appropriate
flags. The correct version:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>deno run <span class="nt">--allow-read</span> <span class="nt">--allow-write</span> data-generation.ts
Check file:///home/ian/projects/personal/deno-experiments/data-generation.ts
Success.
</code></pre></div></div>
<p>It would be quite easy to create a bash alias with those permissions turned on, but
that rather defeats the goal. Security or convenience: pick one!</p>Ian Dickinsonian@iandickinson.me.ukIn part 1, I laid out some reasons for looking using RDF in Typescript using Deno. In this installment, I’ll put together some quick sample data before I start looking at RDF specifically.RDF, Typescript and Deno Part 1: motivation2021-07-04T00:00:00+01:002021-07-04T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-07-04/rdf-typescript-and-deno<p>So a few things I’ve been mulling over recently have come together into a,
doubtless not very sensible, idea to play with some new tech. Well, new to
me anyway.</p>
<p>First off, there’s an ongoing buzz around Vue 3, which has now reached the
<a href="https://github.com/vuejs/vue-next/releases/tag/v3.1.0">3.1 release</a>. I think
some of the ideas and goals for Vue 3 are interesting, and worth exploring. I’m
not yet fully conviced about the composition API (which I should write about)
one day, but to be fair I’ve not really tried to build a composition-API app yet.</p>
<p>Then there was Ryan Dahl, the
<a href="https://changelog.com/podcast/443">founder of Deno on the ChangeLog</a>. I knew
<strong>of</strong> Deno, but didn’t know much <strong>about it</strong>. The flaws in NodeJS that Deno
wants to address are valid concerns, and the approach sounds solid.</p>
<p>Deno is written in <a href="https://www.typescriptlang.org/">TypeScript</a>, something else
I’ve been meaning to get to grips with. So I played with the first few exercise
from <a href="https://exercism.io/my/tracks/typescript">Exercism’s TypeScript track</a>.
Exercism has long been one of my favourite ways of just getting a feel for a
new language. Each problem only takes a short while, you know definitely when
you’ve solved the problem (because the tests pass), and solving allows you to look
at the other community solutions, which is often the most instructive part.</p>
<p>And finally, arising from thinking about a new project at work,
I’ve wanted for a while to have
a play with the <a href="https://rdf.js.org/">RDF libs for JavaScript</a>. While the range
of libraries available for RDF-Js look reasonable, the “getting started” docs
are basically MIA.</p>
<p>So, to the doubtless not very sensible plan: to spend some time looking at an
app in the intersection of the above technologies, and blog about what I learn
along the way.</p>
<p>Rougly speaking, my plan of attack is to start small, with just the core elements,
and build outwards from there. Step 1 will be to read and write some basic
RDF with a simple Typescript program.</p>Ian Dickinsonian@iandickinson.me.ukSo a few things I’ve been mulling over recently have come together into a, doubtless not very sensible, idea to play with some new tech. Well, new to me anyway.Week notes: 4 Jul, 20212021-07-04T00:00:00+01:002021-07-04T00:00:00+01:00https://iandickinson.me.uk/blog/blog/2021-07-04/week-notes-4-jul-2021<p>Things I’ve been reading and thinking about recently, including bowl carving,
dark fish and writing better user stories by reading bad examples!</p>
<ul>
<li>physics is not the only science with <a href="https://twitter.com/DrAndrewThaler/status/1406922566070157314">dark mysteries</a>.
I also enjoyed the suggestion further down the thread that we should
build a Large Haddock Collider to seek the cod particle.</li>
<li>I love David Fisher’s carved bowls. Here’s a recent piece, in the shape
of a <a href="https://davidffisher.com/2021/06/23/bird-bowl-from-straight-grain/">bird in flight</a></li>
<li>really comprehensive round-up of <a href="https://www.smashingmagazine.com/2021/06/complete-guide-accessibility-tooling/">accessibility testing tools</a>
by <a href="https://twitter.com/NicMakesStuff">Nic Chan</a></li>
<li>I discovered by accident that, while access to the <a href="https://www.oed.com">Oxford English Dictionary</a>
is commercial, many libraries are already subscribed. I’m a member of Somerset Libraries,
and, indeed, I could log in <strong>- for free -</strong> to the OED using just my Somerset library
card ID. Wonderful!</li>
<li>painfully funny/accurate <a href="https://twitter.com/ShitUserStory">shit user stories</a></li>
</ul>Ian Dickinsonian@iandickinson.me.ukThings I’ve been reading and thinking about recently, including bowl carving, dark fish and writing better user stories by reading bad examples!