<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>lochsh</title><link href="https://mcla.ug/" rel="alternate"/><link href="https://mcla.ug/blog/feeds/all.atom.xml" rel="self"/><id>https://mcla.ug/</id><updated>2026-02-25T00:00:00+00:00</updated><entry><title>Pandaí or "pandy" for a tin mug or jug</title><link href="https://mcla.ug/pandy.html" rel="alternate"/><published>2026-02-25T00:00:00+00:00</published><updated>2026-02-25T00:00:00+00:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2026-02-25:/pandy.html</id><summary type="html">&lt;h2&gt;Childhood memories&lt;/h2&gt;
&lt;p&gt;My mother was talking about her childhood summers in rural Donegal, and used
the word "pandy" to describe the tin drinking vessels she was often
tasked with bringing to the men out working, along with a pail of water from the
spring well to fill the vessels from …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Childhood memories&lt;/h2&gt;
&lt;p&gt;My mother was talking about her childhood summers in rural Donegal, and used
the word "pandy" to describe the tin drinking vessels she was often
tasked with bringing to the men out working, along with a pail of water from the
spring well to fill the vessels from. My culturally hungry ears
pricked; could this be a Gaelic word? The initial &lt;i&gt;p-&lt;/i&gt; marks it as
a loan word &amp;mdash; but from which language, and with what meaning?&lt;/p&gt;
&lt;figure&gt;

    &lt;img src="images/twilly-pandy.jpg" alt="a black and white photo taken in
    the 1960s showing three men in their 20s-30s, a young boy, and a woman in
    her late 20s. the men are drinking from glass bottles. the young boy is
    drinking from a tin mug, a 'pandy'."&gt;

    &lt;figcaption&gt;&lt;i&gt;My grandparents and two of my granny's brothers, with my
    uncle as a young boy. My uncle is drinking from a &lt;/i&gt;pandaí&lt;i&gt;. The men, I
    am told, are drinking milky tea from glass bottles.&lt;/i&gt;&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;The word &lt;i&gt;pandaí&lt;/i&gt; does not seem to appear in any major Irish dictionaries,
but searching the digitised parts of Ireland's National Folklore Collection
yields a few usages in Donegal. A selection:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;From &lt;a href="https://www.duchas.ie/en/cbes/4493635/4406045/4521041?HighlightText=panda%C3%AD&amp;amp;Route=stories&amp;amp;SearchLanguage=ga"&gt;near Creeslough&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Tháinic sí annsin agus shín sí an &lt;b&gt;pandaí&lt;/b&gt; dó agus d'ól se achan braon a bhí&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;"She came there and passed the pandy to him, and he drank every drop"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From &lt;a href="https://www.duchas.ie/en/cbes/4428319/4394444/4481910?HighlightText=panda%C3%AD&amp;amp;Route=stories&amp;amp;SearchLanguage=ga"&gt;near Kilcar&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Gheibheadh siad baisín céad uair agus cuireadh siad gráinín ann. Go minic
  chuireadh siad dhorn de min bhuidhe fríd. Chuireadh siad gráinín soda agus
  gráinín salainn isteach leobhtha annsin. Chuireadh siad &lt;b&gt;pandaí&lt;/b&gt; blaithche
  isteach annsin agus mheasgadh siad na ceithre rudaí le chéile.&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;A description of how to make soda bread; &lt;i&gt;pandaí
  &lt;a href="https://en.wiktionary.org/wiki/bl%C3%A1ithche#Irish"&gt;blaithche&lt;/a&gt;&lt;/i&gt; = "pandy of
  buttermilk".&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img src="images/pandy.png" alt="a photo of a pandy made by John Doherty"&gt;
&lt;figcaption&gt;&lt;i&gt;A &lt;/i&gt;pandaí&lt;i&gt; made by John Doherty, taken from Conor Thomas
Caldwell's PhD thesis&lt;/i&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;My family only called the small drinking vessels "pandies", with
larger tin vessels (as used for getting water from the well or collecting milk
from the cows) called pails or buckets. There are examples of "pandy"
also being used for these larger vessels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.duchas.ie/en/cbes/4481744/4408451/4481256?HighlightText=pandy&amp;amp;Route=stories&amp;amp;SearchLanguage=ga"&gt;near Glendowan&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;"When a heifer calves you are to put a palm branch and a penny at the
bottom of the &lt;b&gt;pandy&lt;/b&gt; when you are milking her for the first time. This
saves her from witchcraft."&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These corroborating examples are pleasing, but do not get us any closer to
understanding the origin of the word. There are a few usages of the word with divergent
meanings that perhaps hold the key: in Munster, "pandy" appears to refer
to
&lt;a href="https://www.duchas.ie/en/cbes/4921760/4904208/5215639?HighlightText=pandy&amp;amp;Route=stories&amp;amp;SearchLanguage=ga"&gt;mashed
potatoes&lt;/a&gt;
(see &lt;a href="https://en.wikipedia.org/wiki/Champ_(food)"&gt;"poundies"&lt;/a&gt; in Ulster&lt;sup id="fnref:champ"&gt;&lt;a class="footnote-ref" href="#fn:champ"&gt;1&lt;/a&gt;&lt;/sup&gt;), and
&lt;a href="https://www.duchas.ie/en/cbes/4493627/4405070/4514525?HighlightText=pandy&amp;amp;Route=stories&amp;amp;SearchLanguage=ga"&gt;some&lt;/a&gt;
&lt;a href="https://www.duchas.ie/en/cbe/9001854/7191125?HighlightText=pandy&amp;amp;Route=items&amp;amp;SearchLanguage=ga"&gt;sources&lt;/a&gt; also use it to refer to receiving a beating. In fact, we find a version
of &lt;i&gt;pandaí&lt;/i&gt; with slenderised consonants as &lt;i&gt;peaindí&lt;/i&gt;&lt;sup id="fnref:peaindí"&gt;&lt;a class="footnote-ref" href="#fn:peaindí"&gt;2&lt;/a&gt;&lt;/sup&gt; in &lt;a href="https://www.teanglann.ie/en/fgb/peaind%c3%ad"&gt;Ó Dónaill's
dictionary&lt;/a&gt;, with meanings "tin
mug" and "mashed potatoes (with milk and butter)".&lt;/p&gt;
&lt;p&gt;What do tin mugs, mashed potatoes, and physical beatings have in common? The clue
is in the Ulster word "poundies" for mashed potato with sybies: all three
involve pounding! Tin mugs are hammered into shape, potatoes are pounded
into mash, and alas schoolchildren of yore were routinely whacked. It would
seem to me that "pound" was borrowed into Irish to make &lt;i&gt;pandaí&lt;/i&gt;, where in
this instance the suffix &lt;i&gt;-aí&lt;/i&gt; makes it "thing that is pounded" or
(pleasingly) "poundee" &amp;mdash; and then
from there it was retained in some Hiberno-Englishes as "pandy".&lt;/p&gt;
&lt;p&gt;To demonstrate the pounding: travelling tinsmiths would make things like pandies to sell. You can watch
&lt;a href="https://en.wikipedia.org/wiki/John_Doherty_(musician)"&gt;Johnny Doherty&lt;/a&gt; make
one in the 1972 documentary &lt;a href="https://digitalfilmarchive.net/media/fiddler-on-the-road-2190"&gt;&lt;i&gt;Fiddler on the
Road&lt;/i&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/_8DShjWdGwc?si=ZHG3FISHjfWxEZ9S&amp;amp;start=405" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;

&lt;h2&gt;An alternative etymology&lt;/h2&gt;
&lt;p&gt;I was pleased with my above proposed etymology, but a subsequent discovery has
me questioning it.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.collinsdictionary.com/dictionary/english/pandy"&gt;Collins' English
dictionary&lt;/a&gt; defines "pandy" as "(in schools) a stroke
on the hand with a strap as a punishment", and notes the term is primarily used
in Scotland and Ireland&lt;sup id="fnref:belt"&gt;&lt;a class="footnote-ref" href="#fn:belt"&gt;3&lt;/a&gt;&lt;/sup&gt;. The etymology is proposed as deriving from the
imperative &lt;i&gt;pande manum&lt;/i&gt;, Latin for "hold out [your] hand".
This seems to have been issued
to pupils by teachers, at a time when Latin was still used in schools, as
described
in James Wilson's &lt;a href="https://www.isle-of-man.com/manxnotebook/barovian/n136_103.htm"&gt;&lt;i&gt;Early Recollections of Life at
King William's
College&lt;/i&gt;&lt;/a&gt; on The
Isle of Man. Both "pandy" and &lt;i&gt;pande manum&lt;/i&gt; are used to refer to this
punishment in various English language texts&lt;sup id="fnref:texts"&gt;&lt;a class="footnote-ref" href="#fn:texts"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;So did "pandy" come to Irish via this restricted meaning,
and spread in usage to other things that were struck? Or does the word
"poundies" suggest that the usage for mashed potatoes at least evolved
separately? I do stand by the idea that the tin mugs take their
name from being struck during their manufacture, but whether this came from
English "pound" or "pandy" (for a school beating), I cannot say.&lt;/p&gt;
&lt;h2&gt;Usages of &lt;i&gt;pandaí&lt;/i&gt; or "pandy"&lt;/h2&gt;
&lt;figure&gt;
&lt;img src="images/pandy-map.svg" alt="Map of usages of pandaí/pandy"&gt;
&lt;figcaption&gt;&lt;i&gt;Map of uses in Ireland of &lt;/i&gt;pandaí&lt;i&gt; or "pandy". The markers
have been somewhat roughly placed. The only usages I could find in Scotland or
the Isle of Man were in English and referred to the school punishment.&lt;br&gt;&lt;br&gt;The
Munster
&lt;a
href="https://www.duchas.ie/en/cbe/9001854/7191125?HighlightText=pandy&amp;Route=items&amp;SearchLanguage=ga"&gt;usage&lt;/a&gt; for a beating describes a horse's feet crushing a fox as having "made a pandy
of him", which might just be referring to getting mashed like a potato.&lt;/i&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Below is a list of usages of &lt;i&gt;pandaí&lt;/i&gt; or "pandy" to mean something along
the lines of "tin mug". All are from Donegal, except one from Mayo.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In Seán Ó hEochaidh's &lt;i&gt;Sean-chainnt Theilinn&lt;/i&gt; (1955), &lt;i&gt;pandaí&lt;/i&gt; is
  glossed as "a tin pot", and used in the saying &lt;i&gt;Tá sé go h-oiread an
  &lt;b&gt;phandaí&lt;/b&gt;&lt;/i&gt;. If I understand correctly this means "it's as big as a pandy"
  and is used to describe small tasks, or tasks near their
  completion.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Pól Ó Seachnasaigh's &lt;a href="https://mural.maynoothuniversity.ie/id/eprint/4505/1/P%C3%B3l_%C3%93_Seachnasaigh_-_Tr%C3%A1chtas_PDF.pdf"&gt;&lt;i&gt;Eagrán de na scéalta idirnáisiúnta
ó na Cruacha Gorma
a bhailigh Seán Ó hEochaidh
do Choimisiún Béaloideasa Éireann
i 1947 agus
1948&lt;/i&gt;&lt;/a&gt; (2012), stories collected from the Bluestacks by Seán Ó
hEochaidh are reproduced. Story 26: &lt;blockquote&gt;&lt;i&gt;Dúirt an seanduine leis an bhean ar ais
go gcaithfeadh sí éirí, agus an bhó a bhleán, bhí bó ann i ndiaidh breith, agus
&lt;b&gt;pandaí&lt;/b&gt; den
bhainne a thabhairt dó, nó nach gcuirfeadh sé isteach an
oíche.&lt;/i&gt;&lt;/blockquote&gt; "The old
man said to the woman again she must get up, and milk the cow, the cow was
after giving birth, and bring a pandy of milk, or he wouldn't pass the night."&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In a song collected in the Bluestacks, published in
  &lt;a href="https://www.jstor.org/stable/20522563"&gt;Béaloideas, Iml. 68 (2000)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Gerard Stockman's &lt;a href="https://www3.smo.uhi.ac.uk/oduibhin/leabharthai/Stockman%20(1974),%20The%20Irish%20of%20Achill,%20Co%20Mayo.pdf"&gt;&lt;i&gt;The Irish of Achill, Co.
  Mayo&lt;/i&gt;&lt;/a&gt; (1974),
  &lt;i&gt;pandaí&lt;/i&gt; is glossed as "an aluminium mug"&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Pádraig Ó Baoighill's writing, including in &lt;i&gt;Srathóg Feamnaí agus
  Scéalta Eile&lt;/i&gt; (2001): &lt;i&gt;Ó bhreacadh na maidne bhí fear an oileáin ina
  shuí agus &lt;b&gt;pandaí&lt;/b&gt; de tae dhubh déanta aige.&lt;/i&gt; "[...] and he made a pandy of black
  tea."&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Conor Thomas Caldwell's &lt;a href="https://www.academia.edu/9727990/Did_you_hear_about_the_poor_aul_travelling_fiddler_The_Life_and_Music_of_John_Doherty"&gt;&lt;i&gt;'Did you hear about the poor old travelling fiddler?' &amp;ndash; The Life
  and Music of John Doherty&lt;/i&gt;&lt;/a&gt; (2013)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In this &lt;a href="https://www.geograph.ie/photo/2087988"&gt;inscription&lt;/a&gt; in
  &lt;a href="https://maps.app.goo.gl/cWbKB7mjWMF1DFJQ6"&gt;Edenfinfreagh&lt;/a&gt;, telling the story
  of John Doherty's brother Mickey escaping violence from Black and Tans by
  making a &lt;i&gt;pandaí&lt;/i&gt; on the spot to demonstrate he was just a poor
  tinsmith.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Diarmuid Ó hAirt's &lt;a href="https://web.archive.org/web/20240721234049/http://homepage.eircom.net/~gfg/p.htm"&gt;&lt;i&gt;Cnuasach Conallach: A Computerized Dictionary of
  Donegal Irish&lt;/i&gt;&lt;/a&gt;
  defines it as &lt;i&gt;Soitheach stáin&lt;/i&gt; ("tin vessel"), and uses sources
  collected from The Frosses, Lettermacaward, and Glencolmcille.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In these interviews in
  &lt;a href="https://www.bealoideasbeo.ie/bealoideas/httpdocs/trascribhinni/piosai/019t041_tr.pdf"&gt;Teelin&lt;/a&gt;
  and
  &lt;a href="https://www.bealoideasbeo.ie/bealoideas/httpdocs/trascribhinni/piosai/045t053_tr.pdf"&gt;Cloghan&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In a song collected in Patrick MacGill's &lt;a href="https://upload.wikimedia.org/wikipedia/commons/9/9d/Songs_of_Donegal_%28IA_songsofdonegal00macgrich%29.pdf"&gt;&lt;i&gt;Songs of
  Donegal&lt;/i&gt;&lt;/a&gt;
  (1921). Page 19: "In all things handy/Thatching a haystack or mending a
  &lt;b&gt;pandy&lt;/b&gt;"&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Seaghán 'ac Meanman's works, including in &lt;i&gt;Mám Eile as an Mhála
  Chéadna&lt;/i&gt; (1954): &lt;i&gt;Níorbh' fhada go dtáinig an chomharsanach a ba
  deirean-naighe a bhí astigh an oidhche roimh ré, agus
  bhí &lt;b&gt;pandaí&lt;/b&gt; bainne leis.&lt;/i&gt; "[...] and he had a pandy of milk with him."&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Joy Elliott's &lt;a href="https://louishemmings.com/wp-content/uploads/2016/10/Louis-Joy-A5sLR-29-04-2011.pdf"&gt;&lt;i&gt;Derby to Donegal &amp;ndash; by
  design&lt;/i&gt;&lt;/a&gt; (2011): "Inside I was invited to a
‘&lt;b&gt;pandy&lt;/b&gt;’ of tea. A pandy was a tin mug, usually blackened from
being nudged into the fire, so tea ended up being stewed this
way."&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Brighid "Biddy" McLaughlin's &lt;i&gt;Tales of a Patchwork Life&lt;/i&gt; (2024): "a
  tin &lt;b&gt;pandy&lt;/b&gt; made by Irish travellers that my son Johnny still drinks from"&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://donegalgaa.ie/2023/09/14/calling-on-amateur-photographers-the-inaugural-michael-jack-pandy-competition-awaits-your-entry/"&gt;Referring to a metal trophy&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other usages can be found by searching &lt;a href="https://www.duchas.ie"&gt;duchas.ie&lt;/a&gt;. The
&lt;a href="https://www.corpas.ie/en/cng/?q=pandy"&gt;National Corpus of Irish&lt;/a&gt; also records
"pandy" in a couple audio interviews that I haven't listed above.&lt;/p&gt;
&lt;h2&gt;The panda in the room&lt;/h2&gt;
&lt;p&gt;I should mention that "panda", for the animals, has been borrowed into Irish
and the plural is &lt;i&gt;pandaí&lt;/i&gt;. This is of course unrelated etymologically! 🐼&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:champ"&gt;
&lt;p&gt;Personally I've only ever called it "champ". I've seen "poundies" in
Peadar O'Donnell's writing. Possibly it is used outside Ulster too, and it
might not always refer to mashed potatoes and sybies.&amp;#160;&lt;a class="footnote-backref" href="#fnref:champ" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:peaindí"&gt;
&lt;p&gt;I haven't found any clear record of anyone using this form for tin
mugs. There are a couple usages of it in &lt;a href="https://www.corpas.ie/en/cng/?q=peaind%C3%AD"&gt;The National Corpus of
Irish&lt;/a&gt; but I'm not sure what
they're referring to. The first one is a food, I don't know about the second.&amp;#160;&lt;a class="footnote-backref" href="#fnref:peaindí" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:belt"&gt;
&lt;p&gt;Thankfully corporal punishment was a thing of the past when I went to
school, but my parents both received &lt;a href="https://en.wikipedia.org/wiki/Tawse"&gt;the
belt&lt;/a&gt; as punishment. They had no
recollection of the term "pandy" ever being used in relation to it.
It is
&lt;a href="https://dasg.ac.uk/fieldwork/view/SW52ZXJuZXNzSEJhcnJvbnBlcnNvbmFsbWlzY3xhIHBhbmR5fGlkcDE1NzA0OTk2OHx8cGFuZHxyMnx8fGFsbA=="&gt;recorded&lt;/a&gt;
in the DASG fieldwork in Inverness.&amp;#160;&lt;a class="footnote-backref" href="#fnref:belt" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:texts"&gt;
&lt;p&gt;A non-exhaustive list of usages referring to hitting the hands with a
strap or cane:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1715, Scotland, &lt;i&gt;pande manum&lt;/i&gt;: &lt;a href="https://en.wikisource.org/wiki/Sermon_preached_by_Mr._James_Rows_(sic),_in_St._Geil%27s_Kirk_at_Edinburgh,_which_has_been_commonly_known_by_the_name_of_Pockmanty_preaching"&gt;Sermon preached by Mr. James Rows (sic), in St. Geil's Kirk at Edinburgh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;1833, Scotland, &lt;i&gt;pandies&lt;/i&gt;: John Kennedy's &lt;i&gt;Geordie Chalmers; or,
  the Law in Glenbuckie&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;1863, England, &lt;i&gt;pandied&lt;/i&gt;: Charles Kingsley's &lt;a href="https://www.pagebypagebooks.com/Charles_Kingsley/The_Water_Babies/Chapter_V_p12.html"&gt;&lt;i&gt;The Water-Babies&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;1917, Ireland, &lt;i&gt;pandies&lt;/i&gt;: James Joyce's &lt;a href="https://archive.org/details/in.ernet.dli.2015.27989/page/177/mode/2up?q=pandies"&gt;&lt;i&gt;A Portrait of the Artist
  as a Young Man&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="footnote-backref" href="#fnref:texts" title="Jump back to footnote 4 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/></entry><entry><title>Goidé mar a deirtear "frog" i nGaedhilg?</title><link href="https://mcla.ug/froganna.html" rel="alternate"/><published>2026-02-11T00:00:00+00:00</published><updated>2026-02-11T00:00:00+00:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2026-02-11:/froganna.html</id><summary type="html">&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/1.0.40/jquery.csv.js"&gt;&lt;/script&gt;

&lt;p&gt;&lt;link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
     loading="lazy"
     integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
     crossorigin=""/&gt;&lt;/p&gt;
&lt;script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
     integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
     crossorigin=""&gt;&lt;/script&gt;

&lt;script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster-src.js"&gt;&lt;/script&gt;
&lt;p&gt;&lt;link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css" /&gt;
&lt;link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;script
    src="https://unpkg.com/leaflet.markercluster.freezable@1.0.0/dist/leaflet.markercluster.freezable.js"
    integrity="sha384-QXTyM8sAAM5XAUeRoyzNadlfH7KuYt0C6i9O/T2vFb4wGIKwL9Ak++3y3JBqfGyg"
    crossorigin="anonymous"
&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;script src="../static/froganna/map.js"&gt;&lt;/script&gt;

&lt;h2&gt;Cuairteoir gan iarraidh: an uninvited guest&lt;/h2&gt;
&lt;p&gt;Two months ago I was sitting on the sofa cuddling my cat when, out of the
corner of my eye, I seen something small and dark hop into the room through the
open doorway. I knew I'd seen a frog, but my brain was …&lt;/p&gt;</summary><content type="html">&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/1.0.40/jquery.csv.js"&gt;&lt;/script&gt;

&lt;p&gt;&lt;link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
     loading="lazy"
     integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
     crossorigin=""/&gt;&lt;/p&gt;
&lt;script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
     integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
     crossorigin=""&gt;&lt;/script&gt;

&lt;script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster-src.js"&gt;&lt;/script&gt;
&lt;p&gt;&lt;link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css" /&gt;
&lt;link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;script
    src="https://unpkg.com/leaflet.markercluster.freezable@1.0.0/dist/leaflet.markercluster.freezable.js"
    integrity="sha384-QXTyM8sAAM5XAUeRoyzNadlfH7KuYt0C6i9O/T2vFb4wGIKwL9Ak++3y3JBqfGyg"
    crossorigin="anonymous"
&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;script src="../static/froganna/map.js"&gt;&lt;/script&gt;

&lt;h2&gt;Cuairteoir gan iarraidh: an uninvited guest&lt;/h2&gt;
&lt;p&gt;Two months ago I was sitting on the sofa cuddling my cat when, out of the
corner of my eye, I seen something small and dark hop into the room through the
open doorway. I knew I'd seen a frog, but my brain was yet to accept this
unlikelihood. I turned my head to see the dark shape on the floor, still now.
Then it hopped again: there was a frog in the house! The wee lad was massive as
well, or such was my perception, faced with the intrusion as I was.&lt;/p&gt;
&lt;p&gt;&lt;img src="../images/froganna/frog.jpeg" alt="A slightly disgruntled Common Frog
    under a pint glass" style="max-height: 300px;"&gt;&lt;/p&gt;
&lt;p&gt;We transferred him safely outside. Before he leapt away into the darkness, our
eyes met, and I understood the task he had bequeathed me: I knew I must find
all the Gaelic words for frog.&lt;/p&gt;
&lt;h2&gt;A map of words for frogs across the Gaelic world&lt;/h2&gt;
&lt;div id="map-container"&gt;
&lt;div id="map" style="height: 600px; width: 95%; margin: auto"&gt;&lt;/div&gt;
&lt;button id="disable-clustering"&gt;Disable clustering&lt;/button&gt;
&lt;button id="enable-clustering"&gt;Enable clustering&lt;/button&gt;
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
Above is a map showing attested words used by local people for "frog". Zooming
out will reveal datapoints in Nova Scotia. The main
sources are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Wagner, H. (1958-1969), &lt;i&gt;Linguistic Atlas and Survey of Irish Dialects (LASID)&lt;/i&gt;, Dublin Institute of Advanced Studies&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Digital Archive of Scottish Gaelic (DASG). University of Glasgow &lt;a href='https://dasg.ac.uk'&gt;&amp;lt;dasg.ac.uk&amp;gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Schools' Collection, National Folklore Collection, University College Dublin &lt;a
  href=https://www.duchas.ie&gt;&amp;lt;duchas.ie&amp;gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tobar an Dualchais &lt;a href='https://www.tobarandualchais.co.uk'&gt;&amp;lt;tobarandualchais.co.uk&amp;gt;&lt;/a&gt;, Sabhal Mòr Ostaig&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dòrlach's fieldwork, kindly shared by Àdhamh Ó Broin &lt;a
  href="https://www.dorlach.scot"&gt;&amp;lt;dorlach.scot&amp;gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The markers can be filtered by source and by word category using the checkboxes
below the map. Clustering can also be enabled or disabled. When disabled, the
remaining clusters are co-ordinates for which there is more than one data
point.&lt;/p&gt;
&lt;p&gt;The GeoJSON file containing the data can be downloaded
&lt;a href="../static/froganna/data/frogs.json"&gt;here&lt;/a&gt;, licensed under &lt;a
href="https://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;CC BY-NC-SA 4.0&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="../images/froganna/word-map.png" alt="map with words on
locations to show distribution of usage. Leinster and East Ulster do not have
many data points. There are two 'frog' usages in Leinster, and East Ulster has
one each of 'fliuchán', 'lapadán', 'crónán', and 'frog'. Clear patterns include
the use of 'cràigean' and 'gille-cràigean' in a band running northeast across
Scotland from Ardnamurchan to Strathspey. A cluster of 'mial-mhàgain' is clear
around Skye and Raasay. 'Leumachan' is clustered around Assynt and MacKay's
Country in Sutherland, though East Sutherland has 'losgaid' and 'mial-mhàgain'.
Connacht has a very dense variety of words but a spread of usage of 'luascan
lathaí' is visible across Galway and Mayo. In Munster there are two usages of
'cnádán' close to each other in Cork and Waterford, one usage of
'laprachán' in Ring, and one usage of 'lisbín' in Kerry. The rest of
the points in Munster are 'frog'. Donegal has a roughly even spread of 'frog',
    'losgann' and  'lisbín', with a couple usages of 'crónán' and one of
    'luascan lathaí'."
style="max-height: 900px;"&gt;
&lt;figcaption&gt;&lt;i&gt;A map showing recorded usages of words for frog, with categories
of words grouped together (e.g.  &lt;/i&gt;mula-mhàgag&lt;i&gt; displayed as
&lt;/i&gt;mial-mhàgain&lt;i&gt;, &lt;/i&gt;liospán&lt;i&gt; displayed as &lt;/i&gt;lisbín&lt;i&gt;). Nova
Scotia exclusively had &lt;/i&gt;màgan&lt;i&gt; for frog.&lt;/i&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The goal with the words included in the map is to have traceable examples
of local native speakers using each word. I am keen to not allow
this goal to unnecessarily exclude areas where the local language died. Where
a dictionary is the only source of a word, I have not included it, but will
often mention it in the text below. For some words, there are enough secondary
sources that it feels right to include it on the map. These secondary sources
are often from non-native speakers who were experts in a particular area's
language, but which don't name a specific speaker and only refer to a broad
area. There is some judgement involved in what to include and what to exclude,
and I hope my reasoning is made clear both in the details of each
datapoint, and in the writing below.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Click for more information about the sources and data&lt;/summary&gt;
&lt;br&gt;
Resources like the LASID and DASG are based on
fieldwork designed to record the words local people used in
everyday speech.  Materials in Ireland's National Folklore Collection, and
those used from Tobar an Dualchais, are largely recordings of storytelling or
other lore. Storytelling, particularly for a recording audience, can be in a
higher register than every day speech&lt;sup id=fnref:1&gt;&lt;a class="footnote-ref"
href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;. This is not to say
that words taken from these resources lack authenticity, just that
their context differs from that of words taken from conversation- and
questionnaire-based linguistic fieldwork.

&lt;br&gt;&lt;br&gt;
Other sources are from books and newspaper articles, where the author was
either a native speaker of the local language, or was reporting on the local
language.

&lt;br&gt;&lt;br&gt;
For sources like The Schools' Collection in Ireland's National Folklore
Collection, the linguistic background of the informants is not made explicit as
in sources like the LASID. If I ever have reason to believe the informant might
not be a native speaker or be a native speaker from somewhere else, I have
included a note. I have not included all examples of &lt;i&gt;frog&lt;/i&gt; from The
Schools' Collection as there are so many!

&lt;br&gt;&lt;br&gt;
I do not intend for the datapoints to indicate that frogs were exclusively
called a particular word in a place, or that a word was exclusively used for
frogs (e.g. &lt;i&gt;leumachan&lt;/i&gt; is &lt;a
        href=https://dasg.ac.uk/fieldwork/view/TGlvbmVsSnVuaW9yU2Vjb25kYXJ5bWFvcmFjaHxsZXVtYWNoYW58ZDBlNjA5fHxsZXVtYWNoYW58cjF8fHxhbGw=&gt;here&lt;/a&gt; recorded
as being used for some beach insect or crusteacean). Many of the words
recorded might have been supplementary to others. Additionally, much of
the data is from the mid 20th century and as such may not reflect current local
vocabulary. Indeed, the local language has sadly died in many of the places
included. I hope that my work here can celebrate dialectal
diversity, preserve the existence of lost words, and provide a fun way to
engage with linguistic heritage.

&lt;h3&gt;Toads&lt;/h3&gt;

Some of the words provided are cited as meaning "toad" by other sources. Not
everyone has a clear linguistic distinction between "frog" (for me, frogs have
shiny skin and jump) and "toad" (for me, toads have dry knobbly skin and
crawl)&lt;sup id=fnref:2&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;. Not everyone's distinction will be the same, especially across
languages. Some of the words found here describe a creature as a crawler, which
certainly evokes toads for me. If you see a word cited as meaning "frog" that for you means "toad",
please bear inter-speaker and geographic variation in mind, as well as the way
words can evolve over time.

&lt;br&gt;&lt;br&gt;
Although words specifically used for toads are also of interest, I have limited
the scope of this project to words used for frogs.

&lt;h3&gt;Phonetic transcription&lt;/h3&gt;
The LASID transcriptions are shown with narrow phonetic transcription brackets
e.g. &lt;span class=ipa&gt;[Lɪːsḳɑːn´]&lt;/span&gt;. This is in accordance with the source
material's explicit description of the transcriptions as phonetic. The narrowness of the transcriptions
varies a little; all fieldworkers seem to aim to be very narrow in terms of
vowel notation, with a detailed vowel chart with many labelled points
provided. A spectrum of consonant palatalisation is allowed for in the notation,
and various non-phonemic fortis/lenis consonant contrasts, alongside the
phonemic ones.  However, some details seem to be inconsistently recorded, like
lack of aspiration on plosives (always shown on Scottish transcriptions, but
only sometimes shown on e.g. &lt;span class=ipa&gt;/sk/&lt;/span&gt; sequences,
where I'd consistently expect an unaspirated &lt;span
class=ipa&gt;/k/&lt;/span&gt;), and velar and palatal off-glides (seemingly only
sometimes shown, but often missing from places I would expect to hear
them, e.g. in Conamara speaker's pronunciation of the language's endonym). Devoicing of consonants seems rarely recorded. It's not clear that
there's any provision for recording approximant realisations of slender r.
Around Gaoth Dobhair I have certainly heard something like &lt;span
class=ipa&gt;[j]&lt;/span&gt; for /r'/, which possibly is recorded in the LASID as /r′′/
to indicate "strong palatalisation".

&lt;br&gt;&lt;br&gt;
I have added my own IPA transcriptions to "translate" the LASID symbols. I am
not providing these because I think they're an improvement; on the contrary,
they're much more annoying to read. I hope that they can be useful to people
with knowledge of the IPA but without knowledge of common Gaelic transcription
conventions. They should be read with the understanding of the apparent
limitations of the source transcription described above.

&lt;/details&gt;

&lt;h2 suffixes&gt;Guide to suffixes&lt;/h2&gt;
&lt;p&gt;Descriptions largely taken from Wiktionary.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span style="color: #fc04a2;"&gt; Irish &lt;i&gt;-án&lt;/i&gt;, Scottish &lt;i&gt;-an&lt;/i&gt;,
    Manx &lt;i&gt;-an&lt;/i&gt; or &lt;i&gt;-ane&lt;/i&gt;&lt;/span&gt;
        &lt;ul&gt;&lt;li&gt;
            &lt;i&gt;lochán&lt;/i&gt;,
            &lt;i&gt;lochan&lt;/i&gt;,
            &lt;i&gt;loghan&lt;/i&gt;.
            "pond, pool, small lake" (diminutive of &lt;i&gt;loch&lt;/i&gt;)
        &lt;/li&gt;
        &lt;li&gt;
            &lt;i&gt;grianán&lt;/i&gt;, &lt;i&gt;grianan&lt;/i&gt;, &lt;i&gt;grianane&lt;/i&gt;. "sunny spot" (from
                    the word meaning "sun" + suffix)
        &lt;/li&gt;
        &lt;li&gt;A suffix used to derive instruments, diminutives, and other nouns
        from primary nouns.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span style="color: #fc04a2;"&gt;Irish &lt;i&gt;-adóir&lt;/i&gt;, Scottish
    &lt;i&gt;-adair&lt;/i&gt;, Manx &lt;i&gt;-der&lt;/i&gt;&lt;/span&gt;
        &lt;ul&gt;&lt;li&gt;
            &lt;i&gt;bréagadóir&lt;/i&gt;,
            &lt;i&gt;breugadair&lt;/i&gt;,
            &lt;i&gt;breageyder&lt;/i&gt;.
            "liar"
        &lt;/li&gt;
        &lt;li&gt;Suffix appended to words to create an agent noun, indicating a
        person who does (or a thing that does) something&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span style="color: #fc04a2;"&gt;Irish &lt;i&gt;-ach&lt;/i&gt;, Scottish &lt;i&gt;-ach&lt;/i&gt;,
    Manx &lt;i&gt;-agh&lt;/i&gt;&lt;/span&gt;
        &lt;ul&gt;&lt;li&gt;
            &lt;i&gt;Éireannach&lt;/i&gt;,
            &lt;i&gt;Èireannach&lt;/i&gt;,
            &lt;i&gt;Erinagh&lt;/i&gt;.
            "Irish person" (noun)
        &lt;/li&gt;
        &lt;li&gt;Forms nouns from other nouns and adjectives with the sense of
        ‘person or thing connected or involved with, belonging to, having’.&lt;/i&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt; &lt;span style="color: #fc04a2;"&gt; Irish &lt;i&gt;-aire&lt;/i&gt;, Scottish
    &lt;i&gt;-aire&lt;/i&gt;, Manx &lt;i&gt;-eyr&lt;/i&gt;&lt;/span&gt;
        &lt;ul&gt;&lt;li&gt;
            &lt;i&gt;iascaire&lt;/i&gt;, &lt;i&gt;iasgair&lt;/i&gt;, &lt;i&gt;eeasteyr&lt;/i&gt;. "Fisherman" (from
                    the word meaning "fish" plus suffix)
        &lt;/li&gt;
        &lt;li&gt;Forming nouns from nouns and adjectives with the sense of ‘person
        or thing connected or involved with, belonging to, having’&lt;/li&gt;
        &lt;/ul&gt;
    &lt;li&gt;&lt;span style="color: #fc04a2;"&gt; Irish &lt;i&gt;-anna&lt;/i&gt;, Scottish &lt;i&gt;-an&lt;/i&gt;,
    Manx &lt;i&gt;-yn&lt;/i&gt;&lt;/span&gt;
        &lt;ul&gt;&lt;li&gt;
            &lt;i&gt;bláthanna&lt;/i&gt;,
            &lt;i&gt;blàthan&lt;/i&gt;,
            &lt;i&gt;blaaghyn&lt;/i&gt;.
            "flowers"
        &lt;/li&gt;
        &lt;li&gt;Pluralises some nouns&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="toc"&gt;Thoughts on each word&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#frog"&gt;&lt;i&gt;Frog&lt;/i&gt;: taboo-avoidance?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#losgann"&gt;&lt;i&gt;Losgann&lt;/i&gt;: the peat bog's answer to mythical fire beasts?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#lisbín"&gt;&lt;i&gt;Lisbín&lt;/i&gt;: taboo deformation of &lt;i&gt;losgann&lt;/i&gt;?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#sonasan"&gt;&lt;i&gt;Sonasan&lt;/i&gt;: an etymylogical outlier?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#fliuchán"&gt;&lt;i&gt;Fliuchán&lt;/i&gt;: a lost word from Derry&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#leumachan"&gt;&lt;i&gt;Leumachan&lt;/i&gt; and &lt;i&gt;leumadair&lt;/i&gt;: leaper&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#crónán"&gt;&lt;i&gt;Crónán&lt;/i&gt; and &lt;i&gt;cnádán&lt;/i&gt;: for the frog's sweet song&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#cràigean"&gt;&lt;i&gt;Gille-cràigean&lt;/i&gt;, &lt;i&gt;cràigean&lt;/i&gt;, and &lt;i&gt;cròigean&lt;/i&gt;: well-pawed
lads&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#màgan"&gt;&lt;i&gt;Màgan&lt;/i&gt;, &lt;i&gt;smàigean&lt;/i&gt; and &lt;i&gt;mial-mhàgain&lt;/i&gt;: crawlers&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#lapa"&gt;&lt;i&gt;Laprachán&lt;/i&gt;, &lt;i&gt;lapadán&lt;/i&gt;, &lt;i&gt;laparán&lt;/i&gt; and &lt;i&gt;lapadóir&lt;/i&gt;: paddlers&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#crúbán"&gt;&lt;i&gt;Crúbán claidhe&lt;/i&gt;: what do frogs have to do with crabs?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#breallach"&gt;&lt;i&gt;Breallach lathaí&lt;/i&gt;: a crude comparison? Rated PG&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#lúb"&gt;&lt;i&gt;Lúbóg lathaí&lt;/i&gt; and &lt;i&gt;lúbar lathaí&lt;/i&gt;: for the frog's bendy legs?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#frús"&gt;&lt;i&gt;Frús&lt;/i&gt;: found only in the LASID. Another foreign loan?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#preabaire"&gt;&lt;i&gt;Preabaire na lathaighe&lt;/i&gt;: mud hopper&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#athadán"&gt;&lt;i&gt;Athadán&lt;/i&gt;: Conamara creature&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#tortán"&gt;&lt;i&gt;Tortán&lt;/i&gt;: clod?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="#ceann"&gt;&lt;i&gt;Ceanna-phiullan&lt;/i&gt;: usually used for tadpoles&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="frog"&gt;&lt;i&gt;Frog&lt;/i&gt;: taboo-avoidance?&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/frog.svg" alt="a drawing of a frog's silhouette in
a doorway, casting a long shadow. A St. Bridget's Cross hangs over the
doorway" style="max-height: 500px;"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;I found this in places all over Ireland, but not at
all in Scotland&lt;sup id="fnref:fròg"&gt;&lt;a class="footnote-ref" href="#fn:fròg"&gt;3&lt;/a&gt;&lt;/sup&gt;. Of the 49 LASID locations in Ireland that gave a
response for "frog", 34 gave a variation on this word. Anecdotally it is the
most common word used in Irish today. It is the only word I found native
attestations of on The Isle of Man.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Could the usage of a foreign loan word, from English, be due to a taboo, where
it was feared saying the true name of the creatures would summon them? Christopher
Lewin, a Manx scholar, kindly corresponded with me about Manx words for frogs,
and he suggested the possibility of this taboo.&lt;/p&gt;
&lt;p&gt;My teacher Dubhán Ó Longáin pointed out the belief that frogs entering the home
is an omen of death, which would support this taboo idea. Ireland's National
Folklore Collection would seem to support this as a widely held belief, if not
universal: a sample of 52 "frog omens" (exclusively frogs entering the house or
crossing your path on the road) showed only 8 that signalled good luck, and 2
that signalled marriage or childbirth; the remaining 80% signalled death
or bad luck&lt;sup id="fnref:omens"&gt;&lt;a class="footnote-ref" href="#fn:omens"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;It's of course quite possible that an English loan came to replace a native
word through language contact, without any word-specific pressure, but I don't
know of any other name for an animal that has changed in this way. Some force
must have caused a shift &amp;mdash; that is, unless "frog" was actually the first
word many Gaels heard used for the creatures.&lt;/p&gt;
&lt;p&gt;I learnt during this research that it is a common belief
that frogs are not native to Ireland. Several 17th century texts attribute this
to "the graces of our patron Saint Patrick" (Ó Maonaigh, 1952) or to some
mystical quality of the island. From de Rochefort (1779):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is a peculiarity in this island that there are no venomous animals, not even
frogs, toads, lizards, spiders, nor any other kind, which is a mark of the
purity and goodness of its air. Some persons have tried the experiment whether
any creatures of this sort brought from other places would live here, but it is
a certainty that they die as soon as they arrive in the country; and farther it
is said, that the touch of a native of Ireland proves mortal to any of these
animals in any foreign country whatsoever, and that a circle being made about
any venomous creature with a stick which grew in this island, the animal will
instantly die.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The frog's arrival in Ireland is variously attributed to the Anglo-Norman
invasion of the 12th
century, or to students of Trinity College of the
17th century&lt;sup id="fnref:scharff"&gt;&lt;a class="footnote-ref" href="#fn:scharff"&gt;5&lt;/a&gt;&lt;/sup&gt;, or to William of Orange&lt;sup id="fnref:orange"&gt;&lt;a class="footnote-ref" href="#fn:orange"&gt;6&lt;/a&gt;&lt;/sup&gt;, or some unknown 18th
century introducer in County Down&lt;sup id="fnref:down"&gt;&lt;a class="footnote-ref" href="#fn:down"&gt;7&lt;/a&gt;&lt;/sup&gt;. An account from Gerard of Wales of a
frog being found in Waterford sometime in the 1170s or 1180s&lt;sup id="fnref:gerard-date"&gt;&lt;a class="footnote-ref" href="#fn:gerard-date"&gt;8&lt;/a&gt;&lt;/sup&gt;
speaks of fascination and consternation when the creature is presented at
court&lt;sup id="fnref:topographia"&gt;&lt;a class="footnote-ref" href="#fn:topographia"&gt;9&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] a frog was found, within my time, in the grassy meadows near
Waterford, and brought to court alive before Robert Poer, who was at that
time warden there, and many others, both English and Irish. And when
numbers of both nations, and particularly the Irish, had beheld it with
great astonishment, at last Duvenold&lt;sup id="fnref:king"&gt;&lt;a class="footnote-ref" href="#fn:king"&gt;10&lt;/a&gt;&lt;/sup&gt;, 58th King of Ossory, a man of sense
among his people, and faithful, who happened to be present, beating his
head, and having deep grief at heart, spoke thus:—&lt;br&gt;&lt;br&gt;&lt;b&gt;“That reptile is the
bearer of doleful news to Ireland.”&lt;/b&gt;&lt;br&gt;&lt;br&gt; And uttering a sort of prognostic,
he further said, that it portended, without doubt, the coming of the
English, their threatened conquest, and the subjugation of his own nation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If frogs were indeed brought to Ireland along with colonisation, perhaps the
word "frog" came with them. Even if frogs had long been native to Ireland, but
in isolated populations or select parts such that many Irish people did not
come into contact with them and thus did not have a word for them, it is
conceivable that "frog" did not replace a native word, but was the first name
many people heard applied to the creature.&lt;/p&gt;
&lt;p&gt;While it's likely the Anglo-Norman elite would have called the creatures &lt;a
href=https://anglo-norman.net/entry/raina&gt;&lt;i&gt;raine&lt;/i&gt;&lt;/a&gt;, it is conceivable
many of the footsoldiers would have spoken Middle English and called the
creatures &lt;a href=https://en.wiktionary.org/wiki/frogge#Middle_English&gt;&lt;i&gt;frogge&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=../images/froganna/drumcliffe-cross.jpg alt="Drumcliffe Cross in
    Sligo, from c. 11th century, seemingly showing a frog carved in the stone"&gt;
    &lt;figcaption&gt;
        &lt;i&gt;Drumcliffe Cross in Sligo, from c. 11th century, seemingly
        showing a frog carved in the stone. Evidence of their existence in Sligo at
        that time? Image source: &lt;a
        href=https://www.megalithicireland.com/High%20Cross%20Drumcliffe.htm&gt;Megalithic
       Ireland&lt;/a&gt;&lt;/i&gt;
   &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The idea of much of Ireland having no word for frog that predates Middle
English is not especially attractive to me. Returning to our first
idea, of taboo: Gerard of Wales' account above certainly
gives an early example of frogs being treated as a bad omen. Dubourdieu (1802)
conveys similarly fearful local attitudes in county Down:&lt;/p&gt;
&lt;blockquote&gt;
    [...] there are many stories still
    current of the terror and surprise excited by the view of this
    disgusting though innocent animal, which seems formed to be the prey
    of every voracious creature, either by land or water, within whose
    reach it comes.
&lt;/blockquote&gt;

&lt;p&gt;It is tempting to make the conjecture that the complete lack of usage of
&lt;i&gt;frog&lt;/i&gt; in Scotland is because they are not a bad omen there, thereby
supporting the idea that the word is used as a taboo substitute in Ireland,
where there is evidence of negative superstition.  This is not something I am
able to substantiate. The &lt;a
href=https://www.calum-maclean-project.celtscot.ed.ac.uk/home/&gt;Calum Maclean
Project&lt;/a&gt; provides digital access to over 13 000 manuscript pages of Gaelic
folklore collected across Scotland's Highlands and Islands &amp;mdash; no
particular lore about frogs is available, only an amusing story about a Uist
man seeing one for the first time and thinking it was a fairy. Could the lack
of discussion of frogs implicitly suggest that there was not much lore to
record about them, and hence no negative associations? Perhaps; but Scotland
has plenty of descriptive words for frogs that could easily be taboo
substitutes themselves. Similarly the only lore I've been able to find about
frogs on The Isle of Man, where &lt;i&gt;frog&lt;/i&gt; was used, is the seemingly
pan-Gaelic belief that licking a frog might cure you of many ailments (Clague,
1911)&lt;sup id="fnref:licking"&gt;&lt;a class="footnote-ref" href="#fn:licking"&gt;11&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The truth will remain ambiguous, but personally, I find the idea of "frog" being used euphemistically quite
compelling. One of the words explored below, &lt;i&gt;lisbín&lt;/i&gt;, could be explained by
taboo deformation from &lt;i&gt;losgann&lt;/i&gt;. Various phonetically
intermediate forms are attested, supporting the idea of it being akin to a
"minced oath". Perhaps &lt;i&gt;losgann&lt;/i&gt; was the taboo word everyone was trying to
avoid.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="losgann"&gt;&lt;i&gt;Losgann&lt;/i&gt;: the peat bog's answer to mythical fire beasts?&lt;/h3&gt;
&lt;p&gt;&lt;img
src="../images/froganna/losgann.svg"
alt="A line drawing of a
    frog sitting in front of a fire in an open hearth. The frog has its
    back to the viewer, and there is a pot hanging above the fire."
style="max-height: 600px;"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;I found this across some of Ireland and Scotland, especially in Argyll. Only
three LASID returns gave this word, two of which were in Argyll, and one in
Mayo. Three of the four instances in the Schools' Collection are in
Donegal.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;MacBain (1911) suggests that this word is related to
&lt;a href=https://en.wiktionary.org/wiki/loisc&gt;&lt;i&gt;loisc&lt;/i&gt;&lt;/a&gt;
meaning to burn&lt;sup id="fnref:leprosy"&gt;&lt;a class="footnote-ref" href="#fn:leprosy"&gt;12&lt;/a&gt;&lt;/sup&gt;,
referring to the sting from touching the secretions of the frog's skin.&lt;/p&gt;
&lt;p&gt;&lt;img src="../images/froganna/losgann.png" alt="Proposed etymology for
loscann. Text reads 'losgann, a toad, Ir. loscain, E. Ir. loscann; from
losg above, so named from the acrid secretions of its skin.'"&gt;&lt;/p&gt;
&lt;p&gt;However...I don't believe touching a common frog causes any stinging sensation,
does it? Toads do secrete a &lt;i&gt;bufotoxin&lt;/i&gt;, which can cause an allergic
reaction on contact, but is mostly dangerous when ingested.&lt;/p&gt;
&lt;p&gt;I have a perhaps more compelling idea: The Electronic Dictionary of the Irish
Language entry for &lt;a href=https://dil.ie/30711&gt;&lt;i&gt;loscann&lt;/i&gt;&lt;/a&gt; directed me to
&lt;a href=https://deriv.nls.uk/dcn23/8177/81776163.23.pdf&gt;O'Clery's
Irish Glossary&lt;/a&gt; from 1643:&lt;/p&gt;
&lt;p&gt;&lt;img src="../images/froganna/salamander.png" alt="Text reads: \"LOISGIONN
.i. snasán '[a salamander]'. oir loisgthear é, ⁊ cú cnámha ainm
eile dó 'because it is burnt [loisgthear] and cú cnámha is another
name for it'.\""&gt;&lt;/p&gt;
&lt;p&gt;The notes say the salamander is called &lt;i&gt;loisgionn&lt;/i&gt; "because it is burnt";
salamanders are known to nest in firewood, and in mythology are
associated with fire. Dinneen (1904) also
&lt;a href=https://archive.org/details/foclirgaeilgeagu00dinn/page/443&gt;lists&lt;/a&gt;
"salamander" as a possible translation of &lt;i&gt;loisceann&lt;/i&gt;. The 14th
century manuscript &lt;i&gt;Leabhar Méig Shamhradháin&lt;/i&gt; (McKenna, 1947) seems to
use &lt;i&gt;losguinn&lt;/i&gt; to refer to a dragon&lt;sup id="fnref:dragon"&gt;&lt;a class="footnote-ref" href="#fn:dragon"&gt;13&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Is the humble frog the peat bog's answer to mythical fire beasts of
old? It would seem plausible that &lt;i&gt;losgann&lt;/i&gt; evolved from referring to
dragons and salamanders to the closest creature Ireland has to offer: the frog
(though arguably the newt is a more obvious descendant).&lt;/p&gt;
&lt;p&gt;An alternative hypothesis stems from the discovery that the word "salamander"
has historically been used for crickets and
grasshoppers&lt;sup id="fnref:cricket"&gt;&lt;a class="footnote-ref" href="#fn:cricket"&gt;14&lt;/a&gt;&lt;/sup&gt;.
Crickets are attracted to warmth, and historically have been associated with
the hearth.
Could the evolution instead be (association with fire) -&amp;gt; crickets -&amp;gt;
(association with jumping) -&amp;gt; frogs?&lt;sup id="fnref:synonyms"&gt;&lt;a class="footnote-ref" href="#fn:synonyms"&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;An etymology related to the frog's jumping would certainly be less unusual than
one directly related to salamanders and dragons. Marstrander (1908)
explores possibilities for the etymology of &lt;i&gt;losgann&lt;/i&gt; and
divides Indo-European languages' words for frogs and toads into categories,
named for their:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;croaking (Latin &lt;i&gt;rana&lt;/i&gt;, Latvian &lt;i&gt;var̂de&lt;/i&gt;)&lt;/li&gt;
    &lt;li&gt;skin (shiny for frogs, bumpy for toads) (Sanskrit &lt;i&gt;maṇḍū́ka&lt;/i&gt; is
            given as being from root &lt;i&gt;maṇḍá&lt;/i&gt; meaning scum or cream. Not
            the most convincing...)&lt;/li&gt;
    &lt;li&gt;distinctive hands (French &lt;i&gt;crapaud&lt;/i&gt; for toad)&lt;/li&gt;
    &lt;li&gt;way of moving (jumping for frogs, crawling for toads)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Marstrander complains that a proposed etymology for &lt;i&gt;losgann&lt;/i&gt; to do with
burning seems unlikely due to its uniqueness among other Indo-European
language's words for frogs. Perhaps the missing piece he needed was the
crickets.&lt;/p&gt;
&lt;h4&gt;losgann lathaighe, luascán lathaighe, loscán laithighe, ⁊c.&lt;/h4&gt;
&lt;p&gt;An enjoyable variant of this word, that I found primarily in Mayo and
Galway, is &lt;i&gt;losgann lathaighe&lt;/i&gt; (modern spelling &lt;i&gt;lathaí&lt;/i&gt;), which I
will choose to translate as "mud salamander".&lt;/p&gt;
&lt;h4&gt;East Sutherland's &lt;i&gt;losgaid&lt;/i&gt;&lt;/h4&gt;
&lt;p&gt;An interesting variant found in Embo in East Sutherland is &lt;i&gt;losgaid&lt;/i&gt; &lt;span
class=ipa&gt;[ɫosɡidʹ]&lt;/span&gt;. Noticeably similar is the usage of &lt;i&gt;iosgaid&lt;/i&gt;
in place of &lt;i&gt;easgann&lt;/i&gt; for eel, recorded in Dorian (1978).&lt;/p&gt;
&lt;h4&gt;On spelling variations&lt;/h4&gt;
&lt;p&gt;I have addressed &lt;i&gt;losgann&lt;/i&gt; vs. &lt;i&gt;loscann&lt;/i&gt; in my general &lt;a href="#orthography"&gt;orthography
notes&lt;/a&gt;. These spellings both reflect a pronounciation of something like
&lt;span class=ipa&gt;/ˈl̪ˠɔsˠkən̪ˠ/&lt;/span&gt;, where the first vowel may vary. The
spelling &lt;i&gt;loscán&lt;/i&gt; reflects a pronunciation found in Connacht where the
final consonant is lenis and the final vowel is clear: &lt;span
class=ipa&gt;/ˈl̪ˠosˠkɑːnˠ/&lt;/span&gt;.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="lisbín"&gt;&lt;i&gt;Lisbín&lt;/i&gt;: taboo deformation of &lt;i&gt;losgann&lt;/i&gt;?&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/lisbín.svg" alt="A frog floating in water
with his head just above the surface, with a rippled reflection below him."&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;This word and its variants had only a handful of attestations, all in
Ireland, with no
obvious geographical centre. Usages were found in Kerry (1), Galway (1), Mayo
(1) and Donegal (3).&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This word, most commonly spelt &lt;i&gt;lispín&lt;/i&gt; in the examples I found, isn't in
Ó Dónaill's dictionary. A schoolchild in Listowel, County Kerry
&lt;a href=https://www.duchas.ie/en/cbes/4613715/4611694/4660320&gt;defines&lt;/a&gt; it as
meaning "frog or lizard". Dinneen (1904) lists this word as being found in
Sligo, and meaning "frog".&lt;/p&gt;
&lt;p&gt;The etymology seemed opaque to me initially. It would appear to be a diminutive
of &lt;i&gt;lisp&lt;/i&gt; or &lt;i&gt;liosp&lt;/i&gt; (the suffix &lt;i&gt;-ín&lt;/i&gt; slenderises the final
consonants), but this line of enquiry didn't lead anywhere.&lt;/p&gt;
&lt;p&gt;&lt;a href=https://www.daltai.com/discus/messages/12465/11517.html?1048156283&gt;This
speaker from Donegal&lt;/i&gt;&lt;/a&gt; uses it for a type of fish, and suggests it might be
related to &lt;i&gt;losgann&lt;/i&gt;. If this is the case, I'd expect to be able to find
some intermediate forms. Fanad's Father Mac Giolla Ceara uses &lt;i&gt;liospán&lt;/i&gt;
for "frog" in &lt;i&gt;Ceachta as Leabhar na Cruinne&lt;/i&gt;&lt;sup id="fnref:liospán"&gt;&lt;a class="footnote-ref" href="#fn:liospán"&gt;16&lt;/a&gt;&lt;/sup&gt;.  Ó Dónaill's dictionary
&lt;i&gt;does&lt;/i&gt; list &lt;a href=https://www.teanglann.ie/en/fgb/liosp%C3%A1n&gt;this
spelling&lt;/a&gt; as a variant of &lt;i&gt;loscann&lt;/i&gt;!&lt;/p&gt;
&lt;p&gt;Similarly, in The Schools' Collection I found a
&lt;a
href=https://www.duchas.ie/en/cbes/4428280/4391740/4478383&gt;usage&lt;/a&gt;&lt;sup id="fnref:granny"&gt;&lt;a class="footnote-ref" href="#fn:granny"&gt;17&lt;/a&gt;&lt;/sup&gt;
of &lt;i&gt;luspán&lt;/i&gt;, referring to some kind of small creature found by a
turf bank. Whether it refers to a frog is ambiguous, but to me it seems the
most likely candidate.  Apart from the quality of the initial consonant and
possibly the first vowel, &lt;i&gt;luspán&lt;/i&gt; would likely match the pronunciation
indicated by &lt;i&gt;liospán&lt;/i&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;img
        src=../images/froganna/turf-bank.jpg
        alt="Picture of a turf bank (where
             turf is harvested from a peat bog) showing a puddle at the foot
             of the bank"
        width=70%&gt;
    &lt;figcaption&gt;&lt;i&gt;The foot of a turf bank can be quite wet and muddy, a likely
    place to find a frog. Image source: &lt;a
    href=https://www.geograph.org.uk/photo/1001844&gt;geograph.org.uk&lt;/a&gt;&lt;/i&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In the above section on the word &lt;a
href=#frog&gt;"frog"&lt;/a&gt;, I
explored the idea of "frog" being used to substitute for a taboo "true" name for
the creature. If &lt;i&gt;losgann&lt;/i&gt; was such a taboo name, then the evolutions to
&lt;i&gt;luspán&lt;/i&gt;, &lt;i&gt;liospán&lt;/i&gt;, &lt;i&gt;lispín&lt;/i&gt; could be explained by taboo
deformation &amp;mdash; that is, deliberately phonetically altering a word to avoid
actually saying it (as with "jeepers" for "Jesus").&lt;/p&gt;
&lt;figure&gt;
    &lt;img
        src="../images/froganna/lisbín-evolution.svg"
        alt="diagram showing phonetic evolution of /LɞsgəN/ ⟨loscann⟩ to
        /Lɞsban/ ⟨luspán⟩, to /L'ɪsban/ ⟨liospán⟩ to /L'ɪʃb'in'/ ⟨lispín⟩"
        style="max-height: 250px;"
    &gt;
    &lt;figcaption&gt;&lt;i&gt;Example phonemic transcriptons of the attested words I propose
    are evolutions of &lt;/i&gt;loscann&lt;i&gt; to &lt;/i&gt;lispín&lt;i&gt;. A &lt;/i&gt;síneadh fada&lt;i&gt; on an
    unstressed syllable taken to mean a clear short vowel, as in my experience
    in Donegal. Some further phonetically intermediate stages would be
    grammatically restricted, e.g. &lt;/i&gt;liospáin&lt;i&gt; would be a declension of
    &lt;/i&gt;liospán&lt;i&gt;.&lt;/i&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;If this word is indeed a phonetic variation on &lt;i&gt;losgann&lt;/i&gt;, then the fact
it is also used for lizards might give credence to the idea that the word comes
directly from salamanders, rather than indirectly via crickets (see above
section on &lt;a href=#losgann&gt;&lt;i&gt;losgann&lt;/i&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;h4&gt;lisbín locha&lt;/h4&gt;
&lt;p&gt;A variant I found a single example of, in Mayo, was
&lt;a href=www.duchas.ie/en/cbes/4427846/4350083/4443127&gt;&lt;i&gt;lisbín
locha&lt;/i&gt;&lt;/a&gt;&lt;sup id="fnref:locha"&gt;&lt;a class="footnote-ref" href="#fn:locha"&gt;18&lt;/a&gt;&lt;/sup&gt;,
which we might translate as "loch salamander".&lt;/p&gt;
&lt;h4&gt;Use of &lt;i&gt;losgann&lt;/i&gt; to mean "semi-aquatic"&lt;/h4&gt;
&lt;p&gt;Meath's Aodh Mac Domhnaill (1802-1867) uses &lt;i&gt;losgann&lt;/i&gt; to mean
"semi-aquatic" (Beckett, 1967). The editor renders &lt;i&gt;lighsgan&lt;/i&gt; and other
various spellings as &lt;i&gt;loscán&lt;/i&gt;. On otters:&lt;/p&gt;
&lt;blockquote&gt;
Is loscán an dobharchú, óir is ar an uisce a ghintear na coileáin agus dá bhrí
sin baineann a mbeatha amach faoi agus os cionn uisce.
&lt;/blockquote&gt;

&lt;p&gt;"The otter is &lt;i&gt;loscán&lt;/i&gt;, for in the water the pups are born and therefore
they spend life out of and in the water."&lt;/p&gt;
&lt;p&gt;The same text uses &lt;i&gt;frag&lt;/i&gt; (rendered &lt;i&gt;frog&lt;/i&gt; by the editor) for "frog".
Does the use of &lt;i&gt;losgann&lt;/i&gt; to mean any semi-aquatic creature
support the idea of it being a taboo word? Perhaps not. However, the usage
seems at odds with all earlier examples given in the &lt;a
href=https://dil.ie/30711&gt;eDIL&lt;/a&gt;. Given our proposed etymology for
&lt;a href="#losgann"&gt;&lt;i&gt;losgann&lt;/i&gt;&lt;/a&gt;, it would seem this usage has come from the previous
use of the word to mean "frog" specifically. Perhaps after the word had become
infrequent, and &lt;i&gt;frog&lt;/i&gt; had become ubiquitous, this more general usage
became possible.&lt;/p&gt;
&lt;h4&gt;Other usages of &lt;i&gt;lisbín&lt;/i&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=http://corpas.ria.ie/index.php?fsg_function=3&amp;fsg_id=1580&gt;An Irish
     telling of The Princess and the Frog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=https://irishplayography.com/play?playid=32411&gt;A character in a play&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=https://maps.app.goo.gl/XHXXoNvcCagYGRGf7&gt;Possibly in the name
  of this beach&lt;/a&gt;, written &lt;i&gt;i nGaedhilg&lt;/i&gt; &lt;a
  href=https://www.rte.ie/news/nuacht/2022/0126/1275968-leanbh-fear-og-maraithe-i-dtimpisti/&gt;in
             this news article&lt;/a&gt; as &lt;i&gt;Trá Lispín&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;In &lt;a
href=https://archive.org/details/manwhoinventedsi0000ofao/page/n5/mode/2up&gt;&lt;i&gt;The Man Who Invented Sin&lt;/i&gt;&lt;/a&gt; by Seán O'Faoláin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="sonasan"&gt;&lt;i&gt;Sonasan&lt;/i&gt;: an etymylogical outlier?&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/sonasan.svg" alt="A smiling frog next to
a daisy"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;I found this word in two places in Wester Ross. It is also stated to be used
in nearby Skye in Forbes (1905).&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In Robertson (1900) p. 364 &lt;i&gt;sonasan&lt;/i&gt; is described as specifically
referring to "the young frog when it has passed the tadpole stage".&lt;/p&gt;
&lt;p&gt;The word can be the nominative plural for &lt;i&gt;sonas&lt;/i&gt;, which means "joy" or
"good fortune". Use of the plural seems uncommon, but it is used this way in a
few old sources:&lt;/p&gt;
&lt;blockquote&gt;
’N uair a rainig mi’n gleannan&lt;br&gt;
B’oirdhearc sealladh nam bruach,&lt;br&gt;
Bho na chaochail an doinionn&lt;br&gt;
’S a thainig &lt;b&gt;sonasan&lt;/b&gt; nuadh&lt;br&gt;
&lt;/blockquote&gt;

&lt;p&gt;"[...] and new joys have come". The above is from a song &lt;i&gt;Cuairt Mhaidne A'Bhuachaille&lt;/i&gt;, by Calum MacEath,
which won a prize at a 1926 Mòd, and was reprinted in
&lt;a href=https://deriv.nls.uk/dcn23/1252/1713/125217135.23.pdf&gt;An Gaidheal&lt;/a&gt;
by An Comunn Gàidhealach.&lt;/p&gt;
&lt;p&gt;In the frog's case, the suffix &lt;i&gt;-an&lt;/i&gt; is being used either diminutively or
to create some other new noun (see
&lt;a href="#suffixes"&gt;suffix guide&lt;/a&gt;). The plural is recorded as
&lt;i&gt;sonasánan&lt;/i&gt; &lt;span class=ipa&gt;[sɔ᷉nəsɑnən]&lt;/span&gt;, &lt;span
class=ipa&gt;[sɔ᷉nəsɑnː]&lt;/span&gt; in Wentworth (1993). It would seem that frogs
are being referred to as "wee joys", or "joyful things".&lt;/p&gt;
&lt;p&gt;Referring to a frog as a "wee joy", while delightful, seemed unexpected to me.
Superficially &lt;i&gt;sonasan&lt;/i&gt; reminds me of &lt;i&gt;snasán&lt;/i&gt;, listed above as a
synonym for &lt;i&gt;loisgionn&lt;/i&gt; (see section on &lt;a
        href=#losgann&gt;&lt;i&gt;losgann&lt;/i&gt;&lt;/a&gt;). This word refers
to polish, stemming from the word &lt;i&gt;snas&lt;/i&gt; for cutting or chipping, perhaps
because of the process of making shellac involves scraping a resin secreted by
bugs from tree bark, melting it into a sheet, then breaking that into small
chips. I have no suggestion for how this might be related to frogs or crickets,
and no justification for why the vowel might have been inserted to create
&lt;i&gt;sonasan&lt;/i&gt;. The knowledge that &lt;a
href=https://www.duchas.ie/en/cbe/9000894/7260368/9085160&gt;burnt frog
innards&lt;/a&gt; were once used for polish seems like a red herring.&lt;/p&gt;
&lt;p&gt;Perhaps we can take this word at face value: as describing the joyful motion of
the leaping young frog, newly be-legged &amp;mdash; or as signifying a positive omen.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;!---
https://x.com/Gaeilgebheo/status/1762187597361594503
https://dasg.ac.uk/fieldwork/view/QWxsaWdpbkpNYWNEb25hbGRzbGlwc3xzb25hc2FufGlkcDExNzkzOTYxNnx8ZnJvZ3xyMzZ8fHxhbGw=
https://dasg.ac.uk/fieldwork/view/SW52ZXJuZXNzS01hY1JhZXNsaXBzfHNvbmFzYW58aWRwMTE1NzUyNjE2fHxmcm9nfHIzN3x8fGFsbA==
---&gt;

&lt;h3 id="fliuchán"&gt;&lt;i&gt;Fliuchán&lt;/i&gt;: a lost word from Derry&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/fliuchán.svg" alt="A frog seeks shelter
from rain under a toadstool. Drops of rain are seen splashing off the toadstool
and the frog's unsheltered back (his head is under the toadstool)."&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;This word is reported as once having been found in
County Derry&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;By the time of the LASID in the 1950s, the fieldworkers could find no
native speakers in Derry. However, a variety of earlier secondary sources
record the word &lt;i&gt;fliuchán&lt;/i&gt; as being used for "frog". I have not found the
word used with this meaning elsewhere.&lt;/p&gt;
&lt;p&gt;&lt;img src="../images/froganna/fliuchán.png"
alt="A newspaper clipping in Gaelic
type with title 'FROG' and body
'A chara, I gCondae Dhoire atá \"fliuchán\" ag
na Gaedhealaidh ar \"frog\". Ní ceart an beithidheach
beag bídeach sin a thabhairt as a ainm. Ní thig linn an Béarla a chur ar
leath-toabh ar fad, acht ní mór dúinn an Ghaedhilg a choinneál glan. Mise,
Cormac'"
title="A chara, I gCondae Dhoire atá 'fliuchán' ag
na Gaedhealaidh ar 'frog'. Ní ceart an beithidheach
beag bídeach sin a thabhairt as a ainm. Ní thig linn an Béarla a chur ar
leath-toabh ar fad, acht ní mór dúinn an Ghaedhilg a choinneál glan. Mise,
Cormac"&gt;&lt;/p&gt;
&lt;p&gt;The word &lt;i&gt;fliuch&lt;/i&gt; means wet, and correspondingly &lt;i&gt;fliuchán&lt;/i&gt; means
"wet thing" or "wetness". In Kerry it is used to refer to rain, see Sjoestedt (1930), and &lt;a
href=https://www.duchas.ie/en/cbes/4678384/4674363/4683533&gt;this&lt;/a&gt; example
in the Schools Collection. It is also used in &lt;a
href=https://www.duchas.ie/en/cbes/4622961/4617138/4627097&gt;this entry&lt;/a&gt;
from Conamara to describe some kind of seafood that people long ago would
have eaten, listed alongside crabs, clams, and seaweed.&lt;/p&gt;
&lt;p&gt;Sources where it used to mean frog:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dinneen (1904) p. 320 "a frog (Der.)"&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cormac (1909) (pictured above) He says that in Derry they call frogs
  &lt;i&gt;fliuchán&lt;/i&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mac Meanman (1940): &lt;i&gt;Ceann aca sin an frog nó an fliuchán mar deirtear i
 gcorr-áit ins an chúigeadh seo.&lt;/i&gt; A Donegal source saying frogs are known as
 &lt;i&gt;fliuchán&lt;/i&gt; elsewhere in Ulster.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mac Gréagóir (1908) (pictured below) A riddle describing frogs has the
  answer &lt;i&gt;fliuchán díge&lt;/i&gt;. It is not specifically attributed to Derry,
  just Ulster.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ciarán Ó Duibhín believes the 'Cormac' in &lt;i&gt;An Claidheamh Soluis&lt;/i&gt; is Séamus
Ó Ceallaigh (1879-1954), whose father was from Draperstown and was raised with
Irish until he was 7 years old. More information is available at
&lt;a href=https://www.ainm.ie/Bio.aspx?ID=57&gt;ainm.ie&lt;/a&gt; and in Whitfield (1994).&lt;/p&gt;
&lt;h4&gt;Fliuchán díge&lt;/h4&gt;
&lt;p&gt;In 1908
&lt;a href=https://www3.smo.uhi.ac.uk/oduibhin/daoine/aoidhmin2.htm&gt;Aoidhmín Mac Gréagóir&lt;/a&gt;
published a series of articles in &lt;i&gt;An Claidheamh Soluis&lt;/i&gt; titled
&lt;i&gt;Sean-Ranna Ultacha&lt;/i&gt; (Eng. old verse of Ulster). A riddle is included:
&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="../images/froganna/fliuchan-dige.png"
alt="A riddle in Gaelic type reading 'Léimeachan léimeachan os na gcloch, Léimeachan léimeachan go dtí an loch.  Freagra — Fliuchán díge.'"
title="Léimeachan léimeachan os na gcloch,
Léimeachan léimeachan go dtí an loch.
Freagra — Fliuchán díge."&gt;&lt;/p&gt;
&lt;p&gt;The riddle asks what jumps over rocks and jumps into the loch. The answer,
&lt;i&gt;fliuchán díge&lt;/i&gt;, we can translate as "wet thing of the
ditch".
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="leumachan"&gt;&lt;i&gt;Leumachan&lt;/i&gt; and &lt;i&gt;leumadair&lt;/i&gt;: leaper&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/leumrachan.svg" alt="drawing of a frog mid-leap"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;I found variants of &lt;/i&gt;leumachan&lt;i&gt; in various parts of Scotland,
especially in West and North Sutherland. Dòrlach's fieldwork found
&lt;/i&gt;leumadair&lt;i&gt; once in the North of Lewis, and The Schools' Collection
records it once in Mayo (as &lt;/i&gt;léimeadóir&lt;i&gt;)&lt;/i&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The etymology of &lt;i&gt;leumachan&lt;/i&gt; seems transparent: &lt;i&gt;leum&lt;/i&gt; + &lt;i&gt;ach&lt;/i&gt; + &lt;i&gt;an&lt;/i&gt;
= "(wee) jumping thing". Similarly for &lt;i&gt;leumadair&lt;/i&gt;: "jumper".
&lt;i&gt;Leumadair&lt;/i&gt; is also used for other leaping
animals, like dolphins&lt;sup id="fnref:welsh-leum"&gt;&lt;a class="footnote-ref" href="#fn:welsh-leum"&gt;19&lt;/a&gt;&lt;/sup&gt; or grasshoppers. Sometimes qualifiers are used: Dòrlach's fieldwork in Scotland found
&lt;i&gt;leumadair-fèoir&lt;/i&gt; ("grass jumper") for grasshopper, which is also found
in the 1819 Manx bible as &lt;i&gt;lheimydyr-faiyr&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;It is possible that &lt;i&gt;leumachan&lt;/i&gt; was also used for frog
by native Manx speakers, as it is given in Fargher (1969),
rendered &lt;i&gt;lheimaghan&lt;/i&gt;. It is likely this was a neologism introduced by
Fargher, however. I couldn't find any native corroboration. Fargher's work is
discussed further in the &lt;a href=#other-words&gt;section&lt;/a&gt; on words not included in the map.&lt;/p&gt;
&lt;h4&gt;Variations&lt;/h4&gt;
&lt;p&gt;Several variations of &lt;i&gt;leumachan&lt;/i&gt; came up, in fact far more commonly than
plain &lt;i&gt;leumachan&lt;/i&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;leumrachan&lt;/i&gt;, Carloway on Lewis&lt;/li&gt;
&lt;li&gt;&lt;i&gt;leumbrochan&lt;/i&gt;, Clashnessie, also on Lewis&lt;/li&gt;
&lt;li&gt;&lt;i&gt;leumbhrochan&lt;/i&gt;, Achiltibuie near Ullapool&lt;/li&gt;
&lt;li&gt;&lt;i&gt;leumnachan&lt;/i&gt;, Drumbuie, Lochalsh&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Indeed, the word &lt;i&gt;léimneach&lt;/i&gt; seems more common in Ireland than
&lt;i&gt;léimeach&lt;/i&gt;. How come?&lt;/p&gt;
&lt;p&gt;In Robertson (1900), &lt;i&gt;leumrachan&lt;/i&gt; is explained as coming about through
&lt;i&gt;dissimilation&lt;/i&gt; from &lt;i&gt;leumachan&lt;/i&gt;. This explanation does not make
sense to me. Dissimilation is a phonetic process where sounds change to make
them more distinct from surrounding sounds, or where sounds that are too
similar to others within a word are removed. There are various proposed reasons
for this, but generally it seems to be done to make a word easier to say, or
more pleasing to the ear. Gaelic examples of this given by others:
&lt;i&gt;dealagán&lt;/i&gt; for &lt;i&gt;gealagán&lt;/i&gt; ("egg white", Quiggin, 1906),
&lt;i&gt;caoláire&lt;/i&gt; for &lt;i&gt;caol sháile&lt;/i&gt;
(&lt;a href=https://www.logainm.ie/en/1165628&gt;logainm.ie&lt;/a&gt;). In English
a common example is rhotic speakers pronouncing "berserk" as "beserk".&lt;/p&gt;
&lt;p&gt;Perhaps it is lack of knowledge on my part, but I don't see how
the insertion of /n/ or /r/ here can be explained by dissimilation.
Certainly the substitution of /r/ for /n/, as in pronunciations of
&lt;i&gt;mná&lt;/i&gt; (e.g. &lt;span class=ipa&gt;/mˠɾˠãː/&lt;/span&gt;) found in most places except
Munster, seems well-described by dissimilation. But the insertion of nasal /n/
after nasal /m/ does not seem well-described by this.&lt;/p&gt;
&lt;p&gt;What if &lt;i&gt;leumnachan&lt;/i&gt; (and thereby &lt;i&gt;leumrachan&lt;/i&gt; &amp;amp;c. by dissimilation)
could be explained by &lt;i&gt;leumnach&lt;/i&gt; being formed from the plural? The Old Gaelic
nominative plural &lt;i&gt;léimmen&lt;/i&gt; gave rise to &lt;i&gt;léimanna&lt;/i&gt; in Ireland and
&lt;i&gt;leuman&lt;/i&gt; in Scotland. The eDIL
records the old spellings of &lt;i&gt;lémennach&lt;/i&gt; and &lt;i&gt;leminnach&lt;/i&gt;. Could these
reflect the suffixation of &lt;i&gt;léimmen&lt;/i&gt;? Beyond the example old spellings, I don't have much to support this &amp;mdash;
except that there are other examples of &lt;i&gt;-ach&lt;/i&gt; suffixation that are made
from the plural: &lt;i&gt;aidhmeannach&lt;/i&gt; ("designing; ambitious", from "aims,
purposes"), &lt;i&gt;greamannach&lt;/i&gt; ("biting, inclined to bite; sticky" from
"grips (n.); bites (n.)"). Perhaps the plural here conveyed repeated jumping.
I find this a more satisfying explanation than the dissimilation
above.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="crónán"&gt;&lt;i&gt;Crónán&lt;/i&gt; and &lt;i&gt;cnádán&lt;/i&gt;: for the frog's sweet song&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/crónan.svg" alt="A drawing of frog with an expanded vocal
sac, with some musical notes to indicate he is croaking"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;Both of these words seem rare, at least for referring to frogs.
&lt;/i&gt;Crónán&lt;i&gt; came up twice in West Donegal, and once in the Fews in Armagh.
&lt;/i&gt;Cnádán&lt;i&gt; was found once each in Waterford and Cork, and is also listed in
some old dictionaries and referred to in articles from the late 1800s. Modern
sources often cite &lt;/i&gt;cnádán&lt;i&gt; as referring to the Natterjack Toad. Cnádán is
one of the words used in an &lt;a
href=https://archive.org/details/bioblanaomhthaan00bede/page/58/mode/2up&gt;1817
edition&lt;/a&gt; of the bible&lt;sup id="fnref:cnádán-bible"&gt;&lt;a class="footnote-ref" href="#fn:cnádán-bible"&gt;20&lt;/a&gt;&lt;/sup&gt;. See &lt;a href=#bibles&gt;bible appendix&lt;/a&gt; for more information.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;Crónán: hummer&lt;/h4&gt;
&lt;p&gt;Both of these words refer to the frog's croaking. The first, &lt;i&gt;crónán&lt;/i&gt; is
translated in Hamilton (1974) as "purring", "humming", and beyond the frog's
croak is also used for other low pitched relatively white sounds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;for a cat's purring, see the &lt;i&gt;sean-cainnt&lt;/i&gt;
&lt;a href=https://www.duchas.ie/en/cbes/4427991/4365534/4468264&gt;collected&lt;/a&gt;
several times in the Schools' Collection: &lt;i&gt;Is ar mhaithe leis fhéin a
dheineann an cat crónán&lt;/i&gt; "the cat purrs for himself", the significance of
which I have seen explained in several diverging ways&lt;/li&gt;
&lt;br&gt;

&lt;li&gt;for the sound of a babbling brook (Sinclair, 1879, p. 320): &lt;i&gt;Aig an allt' tha crònan fann/Air a'
ghaoith tha fàile cùbhraidh&lt;/i&gt;, from a song collected from Argyll-born bard
Eanraig MacIlleBhàin
&lt;/li&gt;
&lt;br&gt;

&lt;li&gt;for the sound of waves crashing onto the shore (Sinclair, 1879, p. 223):
&lt;i&gt;An tonn ri crònan air cladach còmhnard&lt;/i&gt;, from a song collected from Iain
Caimbeul, Bàrd na Leidige.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Slightly less congruous is its use for birdsong (Sinclair, 1879, p. 291),
though I suppose this too can be a pleasant background noise.&lt;/p&gt;
&lt;p&gt;A variant &lt;a href=https://www.duchas.ie/en/cbes/4428321/4394634&gt;recorded&lt;/a&gt; in
Donegal and in The Fews (Dunbar, 2025) is &lt;i&gt;crónán díge&lt;/i&gt;, which we might
translate as "ditch hummer" (ditches often collect water, creating a lovely
froggy habitat).&lt;/p&gt;
&lt;p&gt;What of the etymology of this word? The English word "croon" is &lt;a
href=https://en.wiktionary.org/wiki/croon&gt;thought&lt;/a&gt; to
derive from Middle Dutch &lt;a
href=https://en.wiktionary.org/wiki/cronen#Middle_Dutch&gt;crônen&lt;/a&gt;, which
certainly matches phonetically and loosely in terms of meaning. Perhaps the
word was borrowed directly from there, or from Middle English, or from the
modern form "croon". Regardless, perhaps we can revise our earlier translation of &lt;i&gt;crónán díge&lt;/i&gt; to "ditch crooner" for a more romantic vision.&lt;/p&gt;
&lt;h4&gt;Cnádán: croaker&lt;/h4&gt;
&lt;p&gt;This word seems to most commonly have been used for the plant burdock, see various
&lt;a href=https://www.duchas.ie/en/cbes/4427936/4358938/4454815&gt;sources&lt;/a&gt; in
The Schools' Collection, and again Hamilton (1974).
&lt;br&gt;&lt;br&gt;
Its usage for frogs seems to be onomatopoeic. The Scottish &lt;i&gt;cnàg&lt;/i&gt; &lt;span
class=ipa&gt;/kʰɾãːk/&lt;/span&gt; and &lt;i&gt;gnàg&lt;/i&gt; &lt;span class=ipa&gt;/kɾãːk/&lt;/span&gt; for
the frog's croak are notably similar. It is recorded
&lt;a href=https://www.duchas.ie/en/cbes/5008809/4958019/5055398?HighlightText=cnadan&gt;several&lt;/a&gt;
&lt;a href=https://www.duchas.ie/en/cbes/5009102/4986861/5121908&gt;times&lt;/a&gt; in the The
Schools' Collection as a pejorative for someone who moans or is cranky, and &lt;a
href=https://www.duchas.ie/en/cbes/5009102/4986864/5121908&gt;translated&lt;/a&gt; in this sense as "a croaker".&lt;/p&gt;
&lt;p&gt;When I did first understand this word to be likely onomatopoeic, I wondered if
this would only be the case in places where it is pronounced to begin with
&lt;span class=ipa&gt;/kɾˠ/&lt;/span&gt; (further north in Ireland) rather than &lt;span
class=ipa&gt;/knˠ/&lt;/span&gt; (further south in Ireland).
To me, this was all that would make sense in terms of onomatopoeia.  However,
the only places I found it recorded were firmly in the south of the island: the
LASID records &lt;span class=ipa&gt;[knɑũˈdɑːn]&lt;/span&gt; in Waterford. I think this
just serves to illustrate how arbitrary onomatopoeia can be, easily
demonstrated by comparing animal sounds across languages.&lt;/p&gt;
&lt;h4&gt;Our two singers in unison&lt;/h4&gt;
&lt;p&gt;&lt;a href=https://www.duchas.ie/en/cbes/4428116/4379731/4468703&gt;Signs of
rain&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;i&gt;Nuair aireóchtha na froganna ag crónán agus ag cnádán.&lt;/i&gt;&lt;br&gt;"When
you hear the frogs crooning and croaking."&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="cràigean"&gt;&lt;i&gt;Gille-cràigean&lt;/i&gt;, &lt;i&gt;cràigean&lt;/i&gt;, and &lt;i&gt;cròigean&lt;/i&gt;: well-pawed lads&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/cráigean.svg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;Gille-cràigean&lt;i&gt; was recorded a few times around Ardnamurchan and on Lismore,
and usage of &lt;/i&gt;cràigean&lt;i&gt; then stretches in an unbroken (in the data I
have gathered) band running northeast across Scotland to
Strathspey, where &lt;/i&gt;cròigean&lt;i&gt; is found.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;These words appear to refer to the frog's "hands". Dwelly's dictionary defines
&lt;i&gt;cràg&lt;/i&gt; and &lt;i&gt;cròg&lt;/i&gt; primarily as "large or clumsy hand", with various
other hand or paw definitions given also. Macbain (1911) derives &lt;i&gt;cràigean&lt;/i&gt;
from these words, translating it as "well-pawed one". The addition of
&lt;i&gt;gille&lt;/i&gt; makes it "well-pawed lad".&lt;/p&gt;
&lt;p&gt;I've seen it &lt;a
href=https://x.com/guthan_g/status/637694618478489600&gt;suggested&lt;/a&gt; that this
word is instead derived from &lt;i&gt;cnag&lt;/i&gt; &lt;span class=ipa&gt;/kʰɾãk/&lt;/span&gt;, which
Dwelly defines as "pin; peg; knob". Presumably this would describe the frog as
a wee lump. This seems less likely to me, both from the meaning, and due to the
fact that &lt;i&gt;cràigean&lt;/i&gt; has a long vowel (e.g. &lt;span
class=ipa&gt;[kɾɑ:ɡʹɑ̃ṉ]&lt;/span&gt; is recorded in Badenoch) as in &lt;i&gt;cràg&lt;/i&gt;,
and is also found as &lt;i&gt;cròigean&lt;/i&gt;, reflecting the variants &lt;i&gt;cràg&lt;/i&gt;
and &lt;i&gt;cròg&lt;/i&gt;.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="màgan"&gt;&lt;i&gt;Màgan&lt;/i&gt;, &lt;i&gt;smàigean&lt;/i&gt; and &lt;i&gt;mial-mhàgain&lt;/i&gt;: crawlers&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/magan.svg", alt="drawing of frog crawling"
style="max-height: 600px;"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;All three Nova Scotia datapoints record &lt;/i&gt;màgan&lt;i&gt; for frog. In Scotland
it is more common for this to mean toad. However, its
variant &lt;/i&gt;mial-mhàgain&lt;i&gt; is popular in Scotland for frog, particularly on
Skye and Raasay. &lt;/i&gt;Smàigean&lt;i&gt; was found in East Perthshire, and is also used
for "toad" in other places.&lt;/i&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Dwelly's dictionary defines &lt;i&gt;màg&lt;/i&gt; as "paw; claw; ludicrous term for
the hand", and "seal's paw (Argyll)".
&lt;i&gt;Màigean&lt;/i&gt; is given as "Fat little man; child
beginning to walk; toad; frog; ludicrous term for a man with a creeping or
sprawling gait, or moving on all fours." MacBain (1911) suggests this term for
toads should properly be &lt;i&gt;mial-mhàgain&lt;/i&gt;, meaning "squat beast".
&lt;br&gt;&lt;br&gt;
Certainly there seems to be a strong association with crawling here, hence to
me this word would evoke toads more than frogs. Nevertheless, variants of
&lt;i&gt;mial-mhàgain&lt;/i&gt; appear popular for frogs. On Skye and Raasay this is
often rendered &lt;i&gt;mula-mhàgag&lt;/i&gt;. In Robertson (1898), this is analysed as
epenthesis, noting other examples of vowel insertion like
&lt;i&gt;seana-mhathair&lt;/i&gt; instead of &lt;i&gt;sean-mhathair&lt;/i&gt; for grandmother.
Epenthesis between liquid consonants (l, n, r) followed by certain other
consonants is widespread, but the rules that govern it do vary.  Compare the
various Irish pronounciations of &lt;i&gt;seanmháthair&lt;/i&gt; &lt;a
href=https://www.teanglann.ie/en/fuaim/seanmh%c3%a1thair&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Is the usage of a term associated with crawling because frogs and toads were
undistinguished in some places, or the words got confused? MacBain's
translation of "squat beast" certainly suits frogs well, see also the section
on &lt;a href=#crúbán&gt;&lt;i&gt;crúbán claidhe&lt;/i&gt;&lt;/a&gt;. It's possible these terms take their meaning from the
squatting, rather than movement in that position.&lt;/p&gt;
&lt;p&gt;But what of &lt;i&gt;smàigean&lt;/i&gt;? Is the &lt;i&gt;s-&lt;/i&gt; etymological? MacBain also
defines &lt;i&gt;smàg&lt;/i&gt; as "paw", but compares it to English "smuggle". It seems worth noting that in Proto Indo European, many &lt;i&gt;*s-&lt;/i&gt;
prefixes are theorised to have been optional, or only present in some
inflections&lt;sup id="fnref:s-mobile"&gt;&lt;a class="footnote-ref" href="#fn:s-mobile"&gt;21&lt;/a&gt;&lt;/sup&gt;. Hence the English word "small" and the Irish word
&lt;i&gt;míol&lt;/i&gt; ("animal") are thought to be from the same PIE root meaning "small
animal". Whether the same word could be preserved in a language with and
without the s prefix is not clear to me.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="lapa"&gt;&lt;i&gt;Laprachán&lt;/i&gt;, &lt;i&gt;lapadán&lt;/i&gt;, &lt;i&gt;laparán&lt;/i&gt; and &lt;i&gt;lapadóir&lt;/i&gt;: paddlers&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/lapa.svg" alt="drawing of a frog paddling"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;
&lt;/i&gt;Laprachán&lt;i&gt; or &lt;/i&gt;laprachán lathái&lt;i&gt; was found a few times in Galway and
once in Waterford. &lt;/i&gt;Lapadán&lt;i&gt; had one example each in
Galway and Monaghan, &lt;/i&gt;lapadóir&lt;i&gt; one in Mayo, and &lt;/i&gt;lapadóir lathaí&lt;i&gt;
one in Galway. &lt;/i&gt;Laparán&lt;i&gt; was found once in Limerick, and in a novel by a
Donegal author.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;While &lt;i&gt;màgan&lt;/i&gt; and its variants stem from the word &lt;i&gt;màg&lt;/i&gt;, these
words appear to stem from the word &lt;i&gt;lapa&lt;/i&gt;. Relevant extracts from
Dinneen's dictionary, pp. 419-420:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=pink&gt;&lt;i&gt;lapa&lt;/i&gt;&lt;/span&gt;: a paw, the fist&lt;/li&gt;
&lt;li&gt;&lt;span class=pink&gt;&lt;i&gt;lapach&lt;/i&gt;&lt;/span&gt;: a swamp, a marsh&lt;/li&gt;
&lt;li&gt;&lt;span class=pink&gt;&lt;i&gt;lapadán&lt;/i&gt;&lt;/span&gt;: a kind of sea-fish; also a bird called "diver"; a small
inactive person (Donegal); a clumsy person&lt;/li&gt;
&lt;li&gt;&lt;span class=pink&gt;&lt;i&gt;lapáil&lt;/i&gt;&lt;/span&gt;: act of using the paws, pawing; of a frog swimming
(Connacht)&lt;/li&gt;
&lt;li&gt;&lt;span class=pink&gt;&lt;i&gt;lapaire&lt;/i&gt;&lt;/span&gt;: one that paws or pads with the hand&lt;/li&gt;
&lt;li&gt;&lt;span class=pink&gt;&lt;i&gt;laparnach&lt;/i&gt;&lt;/span&gt;: a wading through water etc.; pawing or handling soft mud
etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ó Dónaill's dictionary lists &lt;i&gt;laparnach&lt;/i&gt; as a variant of
&lt;i&gt;slaparnach&lt;/i&gt;, meaning the act or sound of splashing water. This would seem
to be imitative. The varying use of initial "s" reminds me of variant
"plash" for "splash" in English. This would explain the seemingly incongruous
use of &lt;i&gt;lapach&lt;/i&gt; to mean "marsh": as a description of the sound made while
walking through it. Ó Dónaill lists &lt;i&gt;slaprach&lt;/i&gt; as "wet, soggy land".&lt;/p&gt;
&lt;p&gt;In The Schools' Collection, &lt;i&gt;lapa&lt;/i&gt; is used to refer to a goose's &lt;a
href=https://www.duchas.ie/en/cbes/4921952/4912854/4947435&gt;webbed&lt;/a&gt; &lt;a
href=https://www.duchas.ie/en/cbes/4706359/4706073/4725828&gt;feet&lt;/a&gt;, and also
seemingly a &lt;a
href=https://www.duchas.ie/en/cbes/4921874/4897822/5184841&gt;severed human
hand&lt;/a&gt;.  I haven't been able to find any suggested etymologies for it.
Ó Dónaill defines &lt;i&gt;laprachán&lt;/i&gt; as "toddler; waddler", possibly evoking
crawling. I wonder if there are two etymologies at play here, one associated with
splashing and another with hands. I expect they are one and the same, with the
hand being the splashing implement.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="crúbán"&gt;&lt;i&gt;Crúbán claidhe&lt;/i&gt;: what do frogs have to do with crabs?&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/crubán-claidhe.svg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;This word was found twice, both times on the Curraun
Peninsula, east of Achill Island in Mayo.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This seemingly very local term might be translated as "dyke beastie", with
dyke meaning dry-stone wall ("dry stone wall beastie" doesn't have the
same ring to it, and it is common to call them dykes in Scotland, where
I am from).&lt;/p&gt;
&lt;figure&gt;
&lt;img src="../images/froganna/claidhe.png" alt="Excerpt from The Irish of
Achill showing meaning of claidhe as stone fence"&gt;
&lt;img src="../images/froganna/crúbán-claidhe.png" alt="Excerpt from The Irish
of Achill showing meaning of crúbán claidhe as frog"&gt;
&lt;figcaption&gt;&lt;i&gt;Excerpts from Stockman (1974).
In some other places &lt;/i&gt;claidhe&lt;i&gt; is used to mean "ditch"&lt;/i&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The word &lt;i&gt;crúbán&lt;/i&gt; would appear to refer to an animal with some kind of
notable hands; &lt;i&gt;crúb&lt;/i&gt; is listed in Dinneen's dictionary as meaning "a
claw, a hoof, or paw". The descriptive bounds of these words will of course
vary between individuals, but I would personally not use any of these words to
refer to a frog's..."hands". Perhaps &lt;i&gt;crúb&lt;/i&gt; can be used for any non-human limb
appendage. The diminutive &lt;i&gt;crúibín&lt;/i&gt; has been borrowed into English to
refer to pig trotters as food (to me, a distinctively large food, but
nevertheless...).&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Crúbán&lt;/i&gt; is hard to find written Irish attestations of.
An &lt;a href=https://www.duchas.ie/en/cbes/4428052/4372722&gt;example&lt;/a&gt; in the
 Schools' Collection uses it in
the name for a plant shaped like a hare's paw. It is also listed in Ó
Dónaill's dictionary as referring to a "short potato-ridge at angle to main
ridge", probably describing its shape as similar to some kind of
foot&lt;sup id="fnref:body-parts"&gt;&lt;a class="footnote-ref" href="#fn:body-parts"&gt;22&lt;/a&gt;&lt;/sup&gt;. In Dinneen's dictionary it is
defined as &lt;a href=https://en.wiktionary.org/wiki/crabfish&gt;"crabfish"&lt;/a&gt;, an
archaic term for crab&lt;sup id="fnref:crabfish"&gt;&lt;a class="footnote-ref" href="#fn:crabfish"&gt;23&lt;/a&gt;&lt;/sup&gt;.
In the
LASID, the only places giving &lt;i&gt;crúbán&lt;/i&gt; for crab are Rathlin
Island&lt;sup id="fnref:rathlin"&gt;&lt;a class="footnote-ref" href="#fn:rathlin"&gt;24&lt;/a&gt;&lt;/sup&gt;,
Inishowen, Arran and Kintyre. The DASG also records this
usage in other parts of Argyll. Some places (mostly in Ulster, also in
Scotland, one place in Clare, two in Mayo) are however recorded as
using the similar &lt;i&gt;crúbòg&lt;/i&gt;, sometimes only to refer to big crabs.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="../images/froganna/crúbán-distribution.svg"&gt;
&lt;figcaption&gt;&lt;i&gt;Distribution of &lt;/i&gt;crúb-&lt;i&gt; words for "crab". Additional
datapoint in Inishowen from &lt;a
href=https://www.duchas.ie/en/cbes/4493801/4422210/4539693&gt;The Schools'
Collection&lt;/a&gt;. Mayo outlier also from &lt;a
href=https://www.duchas.ie/en/cbes/5235172/5225583/5261072&gt;The Schools'
Collection&lt;/a&gt;. Jura and Colonsay taken from Scouller (2018).&lt;/i&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Given the geographical distribution of &lt;i&gt;crúb-&lt;/i&gt; words for crabs, I do wonder if the strikingly similar Scottish word &lt;i&gt;crùb&lt;/i&gt; might be
related, which Macbain (1911) gives
as being derived from Norse &lt;i&gt;krjúpa&lt;/i&gt; and cognate with English "creep",
meaning "to squat, crouch". That certainly fits a frog's resting pose extremely
well, and arguably a crab's. If &lt;i&gt;crúbán&lt;/i&gt; does refer to the crab's claws,
would we expect to hear the crab's claw referred to as &lt;i&gt;crúb&lt;/i&gt; in the
places that use this term for crabs? On Islay a crab's claw is recorded as
&lt;a
href=https://dasg.ac.uk/fieldwork/view/UG9ydFdlbXlzc0pNYWNBcnRodXJzbGlwc3xsYWRoYXJ8aWRwMTE1NzYyNTEyfHxjcmFifHI1Mnx8fGFsbA==&gt;&lt;i&gt;ladhar&lt;/i&gt;&lt;/a&gt;,
on Lewis as &lt;a
href=https://dasg.ac.uk/fieldwork/view/Q3Jvd2xpc3RhQ2FuZFBNYWNEb25hbGRtaXNjMXxpb25nbmF8aWRtMzU0NjMzMDR8fGNyYWJ8cjUxfHx8YWxs&gt;&lt;i&gt;iongna&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Perhaps in Ireland, Celtic-origin &lt;i&gt;crobh&lt;/i&gt; (Scottish &lt;i&gt;crubh&lt;/i&gt;, meaning:
hoof, clawed foot, etc.) has merged, phonetically and orthographically,
with Norse-origin &lt;i&gt;crúb&lt;/i&gt;. In Scotland there are some examples of
&lt;i&gt;crubhan&lt;/i&gt;, clearly distinct from &lt;i&gt;crùban&lt;/i&gt;.  Dwelly (1918) lists
&lt;i&gt;crubhan cait&lt;/i&gt; for "cat's paw print", specifically the shape one would
make with their fingers inorder to make such an imprint.  The same meaning is
used in Stewart (1885).&lt;/p&gt;
&lt;p&gt;I am personally satisfied by this explanation. I will elect to officially
update my translation to "dyke squatter".
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="breallach"&gt;&lt;i&gt;Breallach lathaí&lt;/i&gt;: a crude comparison? Rated PG&lt;/h3&gt;
&lt;p&gt;&lt;img src="../images/froganna/breallach.svg" alt="a frog drawn to
recall Boticelli's The Birth of Venus. The frog is standing on a clam shell
with one hand on his breast and the other reaching down" style="max-height: 600px;"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;This term was recorded three times in the LASID, all
in Galway.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;When I first looked up &lt;i&gt;breall&lt;/i&gt; in the dictionary, I was met with a
surprise:&lt;/p&gt;
&lt;p&gt;&lt;img src="../images/froganna/breall-dict.png" alt="A screenshot of teanglann.ie
showing that \&lt;i&gt;breall\&lt;/i&gt; means glans penis or clitoris"&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Breallach&lt;/i&gt; is commonly used for clams. What do frogs, glandes, and clams
have in common? Well, they are all "fleshy" and share a certain shiny sliminess
to their opaque surface. I will note that open clams and mussels look like a vulva.&lt;/p&gt;
&lt;p&gt;The other meanings
listed for &lt;i&gt;breall&lt;/i&gt; in Ó Dónaill's dictionary are:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;(Ugly) protuberance [&lt;i&gt;but is this just referencing the above meaning?&lt;/i&gt;]&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;Blubber lip [&lt;i&gt;again, this could be comparing someone's lips in an
insulting way&lt;/i&gt;]&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;Blemish, defect&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;Rag, clout [&lt;i&gt;presumably meaning patch&lt;/i&gt;]&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;Blunderer, fool [&lt;i&gt;genitals as epithets is common in English at least&lt;/i&gt;]&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;(In phrases) &lt;b&gt;Tá ~ ort&lt;/b&gt;, you are making a silly mistake, making a fool
of yourself [&lt;i&gt;in English you might say you are making an arse of something,
perhaps here they are saying you're making a glans of something&lt;/i&gt;]. &lt;b&gt;Fágadh
~ air&lt;/b&gt;, he was made to look very foolish. &lt;b&gt;Tá ~ orm le mo chuid oibre&lt;/b&gt;,
my work is sadly neglected, very much in arrears.&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;&lt;b&gt;~ a gorma&lt;/b&gt;, knapweed.
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;As per my annotations, I do feel that many of these could be explained via the
anatomical meaning. The &lt;a href=https://dil.ie/6713&gt;eDIL&lt;/a&gt; lists these
meanings: &lt;b&gt;blur, spot, stain, etc.; slur, blemish, etc.; tumour, a hump,
knob or botch; the glans penis, etc. a may game, a mocking stock&lt;/b&gt; and &lt;b&gt;
the round knob at the end of the buailteán or striking part of a flail&lt;/b&gt;. The
last meaning perhaps explains &lt;i&gt;breall a gorma&lt;/i&gt; for knapweed.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="../images/froganna/flail-knapweed.png" alt="photo of knapweed with spiky
ball below flower, and medieval flail weapon with spiky ball on a chain"&gt;
&lt;figcaption&gt;
&lt;i&gt;The spiky ball on the end of a flail resembles the involucre of the
knapweed. Flail image from &lt;a
href=https://medievalbritain.com/type/medieval-life/weapons/medieval-flail/&gt;medievalbritain.com&lt;/a&gt;,
knapweed image from &lt;a
href=https://www.ulsterwildlife.org/wildlife-explorer/wildflowers/common-knapweed&gt;ulster-wildlife.org&lt;/a&gt;&lt;/i&gt; 
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The meanings of "knob" &amp;amp;c. do suggest the frog here could be named for his
shape: I suppose a frog sort of looks like a little lump of mud when resting,
see also the use of &lt;i&gt;tortán&lt;/i&gt; (small clod) for frog at LASID point 35, also
in Galway.&lt;/p&gt;
&lt;p&gt;So, does &lt;i&gt;breallach&lt;/i&gt; really refer to the frog's mucusy skin? Or is it an
insult to the frog, calling him a blemish on the bog? 
Perhaps the "protuberance" meaning could refer to the frog's
vocal sac, a suggestion from my teacher Dubhán Ó Longáin. Or perhaps it is just
calling the frog a wee knob. For now, the origin of this term will remain
mysterious.
&lt;/ul&gt;
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="lúb"&gt;&lt;i&gt;Lúbóg lathaí&lt;/i&gt; and &lt;i&gt;lúbar lathaí&lt;/i&gt;: for the frog's bendy legs?&lt;/h3&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;Collectively I found three usages of these terms, all
in Galway.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;My best guess is that these &lt;i&gt;lúb-&lt;/i&gt; words refer to the frog's bendy legs.
De Bhaldraithe (1945) shows usage of the verb &lt;i&gt;lúb&lt;/i&gt; meaning "to bend", and
De Bhaldraithe (1985) shows usage for a purl stitch when knitting, the feeling
of a twist in one's intestines when scared, and the ability to bend joints.&lt;/p&gt;
&lt;p&gt;I would translate &lt;i&gt;lúbóg lathaí&lt;/i&gt; as "wee bent one of the mud". The variant
&lt;i&gt;lúbar&lt;/i&gt; was a bit more mysterious to me, particularly as one of the
transcriptions from the LASID was &lt;span class=ipa&gt;[ˈlɑbər ˈlɑhiː]&lt;/span&gt; which
doesn't look like "ú" at all. Another transcription of &lt;span class=ipa&gt;[Lu̢.bər
ˈLɑhiː]&lt;/span&gt; convinced me they are the same word, and a derivation from
&lt;i&gt;lúb&lt;/i&gt; seems most likely. I wasn't sure what suffix had been applied; my
rendering of &lt;i&gt;-ar&lt;/i&gt; does not represent any standard suffix. Davis Sandefur
suggested this was probably a realisation of &lt;i&gt;-óir&lt;/i&gt;, thus we would have
&lt;i&gt;lúbóir&lt;/i&gt; meaning "bender".&lt;/p&gt;
&lt;p&gt;Not included on in the map data is &lt;i&gt;lúbán díge&lt;/i&gt;, listed in O'Neill-Lane
(1917) as being found in Oriel (South Armagh, North Louth, South Monaghan,
North-West Meath, East Cavan). I couldn't find any other examples of this
usage. I would translate it as "bent one of the ditch".
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="frús"&gt;&lt;i&gt;Frús&lt;/i&gt;: found only in the LASID. Another foreign loan?&lt;/h3&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;This word was only found once, in LASID point 37 in Carnmore,
Galway. It is corroborated as being used in Carnmore at LASID point 35. I could
find no written attestations.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In imagining ways to write the LASID transcription &lt;span
class=ipa&gt;[frus]&lt;/span&gt; (standard IPA &lt;span class=ipa&gt;[fɾˠusˠ]&lt;/span&gt;), I tried
&lt;i&gt;fr[i][u, ú, o, ó, a, á]s&lt;/i&gt; with various declensions, and the most likely
match I found was &lt;i&gt;fras&lt;/i&gt; or &lt;i&gt;fros&lt;/i&gt; used to mean a shower of rain.
This feels tenuous, although we do have the example of &lt;i&gt;fliuchán&lt;/i&gt; above
for a frog word used for rain elsewhere.&lt;/p&gt;
&lt;p&gt;More compelling to me is the idea that this might be another foreign loan,
 perhaps from
an earlier form of "frog". Wiktionary lists various forms in Middle English,
including &lt;a
href=https://en.wiktionary.org/wiki/frosk#English&gt;&lt;i&gt;frosk&lt;/i&gt;&lt;/a&gt;, &lt;a
href=https://en.wiktionary.org/wiki/frossh#Middle_English&gt;&lt;i&gt;frossh&lt;/i&gt;&lt;/a&gt; and
(most attractively) &lt;a
href=https://en.wiktionary.org/wiki/fross#Middle_English&gt;&lt;i&gt;fross&lt;/i&gt;&lt;/a&gt;.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="preabaire"&gt;&lt;i&gt;Preabaire na lathaighe&lt;/i&gt;: mud hopper&lt;/h3&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;I found only one &lt;a
href=https://www.duchas.ie/en/cbes/4498088/4351276/4502478&gt;attestation&lt;/a&gt; of
this, in Mayo.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Another jumping term is &lt;i&gt;preabaire na lathaighe&lt;/i&gt;: "mud hopper", or "mud
bouncer". Other uses I found of &lt;i&gt;preabaire&lt;/i&gt; in The Schools' Collection
appeared to refer to magpies: &lt;a
href=https://www.duchas.ie/en/cbes/4922245/4863816/5020836&gt;see this familiar
superstition&lt;/a&gt; from Tipperary, and this &lt;a
href=https://www.duchas.ie/en/cbes/4922329/4870637/5055991&gt;riddle&lt;/a&gt; from
Clare. Ó Dónaill's dictionary gives as &lt;i&gt;prebaire na mbánta&lt;/i&gt;
as a possibility for magpie.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="athadán"&gt;&lt;i&gt;Athadán&lt;/i&gt;: Conamara creature&lt;/h3&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;I found only one written attestation of this word, and one phonetic in the
LASID, both in Conamara.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img
src="../images/froganna/athadán.png"
alt="Screenshot of book in Gaelic
type, which reads 'Chonnaic mé chugam thríd an locán,
Tadhg O Lupán agus a chos tinn,
Bárr a bhróige air poll a thóna,
Agus a dhá shúil mhóra a' dul as a cheann?
        Athadán no frog air snamh.'"
title="Chonnaic mé chugam thríd an locán,
Tadhg O Lupán agus a chos tinn,
Bárr a bhróige air poll a thóna,
Agus a dhá shúil mhóra a' dul as a cheann?
        Athadán no frog air snamh."&gt;&lt;/p&gt;
&lt;p&gt;I have seen this riddle repeated across Galway and Mayo in The Schools'
Collection and the LASID&lt;sup id="fnref:riddle"&gt;&lt;a class="footnote-ref" href="#fn:riddle"&gt;25&lt;/a&gt;&lt;/sup&gt;. The version above is from a collection of
Conamara folklore (O'Fothartha, 1892). It is a longer version than the later
ones I have seen in the previously mentioned sources. I might inexpertly
translate it as:&lt;/p&gt;
&lt;blockquote&gt;
I seen through to the puddle/pond [assuming &lt;i&gt;locán&lt;/i&gt; is &lt;i&gt;lochán&lt;/i&gt;]&lt;br&gt;
Timmy McHands and his sore leg [because his legs are bent funny]&lt;br&gt;
The top of his shoe in his arsehole [because of how frogs sit]&lt;br&gt;
And his two big eyes going out his head&lt;br&gt;
&lt;/blockquote&gt;

&lt;p&gt;I can see how it describes a frog, but if there is any of the wordplay that I
usually associate with riddles, it is not apparent to me. Regardless of
my suspicions about the quality of this riddle, the answer in all six other
examples of this riddle is always a word meaning "frog". In the fuller example
here, the answer is "&lt;i&gt;athadán&lt;/i&gt; or &lt;i&gt;frog&lt;/i&gt; swimming". I do not see how the former
could be an alternative answer &amp;mdash; I think it is an alternative name for
the same meaning.&lt;/p&gt;
&lt;p&gt;The only other usage of this word I've been able to find is in the LASID. Point
35, South of Tuam, for some reason lists alternative words for "frog" from
different areas than the one at hand. A word from Conamara is given as &lt;span
class=ipa&gt;[ɑːdɑːn]&lt;/span&gt;. I have read that intervocalic &lt;span
class=ipa&gt;/h/&lt;/span&gt; is deleted in parts of Conamara, so this would appear to
be our word.&lt;/p&gt;
&lt;p&gt;I was perplexed as to what it could mean. I am grateful to Davis Sandefur for
investigating. He asked Criostóir Ó Loingsigh, who had heard &lt;i&gt;eathadán&lt;/i&gt;
for "tadpole" from a Kerry speaker. The root of the word is spelt variously
&lt;i&gt;athaid&lt;/i&gt;, &lt;i&gt;aithid&lt;/i&gt;, &lt;i&gt;eathaid&lt;/i&gt;, &lt;i&gt;feithid&lt;/i&gt;. The initial &lt;i&gt;f-&lt;/i&gt; is not
etymological. The &lt;a href="https://dil.ie/20835"&gt;eDIL&lt;/a&gt; lists various related usages: "A
bird, fowl; a winged creature; a living creature", "a serpent, any venomous
little creature", "a beast". It would seem to be applied in a similar way to
"beastie", though it seems in Conamara it was used to mean a very specific
beastie: the frog.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="tortán"&gt;&lt;i&gt;Tortán&lt;/i&gt;: clod?&lt;/h3&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;I only found this in Ballyglooneen, LASID point 35, in Galway. The
similar &lt;/i&gt;torpán&lt;i&gt; is listed in Dinneen's dictionary with "frog" as a
possible meaning.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Tortán&lt;/i&gt; is listed in Ó Dónaill's dictionary as meaning "clump, tussock",
or "dumpy person". Similarly, &lt;i&gt;torpán&lt;/i&gt; is listed as "(small) clump or
clod" or "roundish thing; lumpish person, pot-bellied person". Perhaps it is
used for frogs to compare them to clods of turf, or refer generically to small
lumps of creatures.&lt;/p&gt;
&lt;p&gt;Interestingly, in the context of the &lt;a href="#crúbán"&gt;&lt;i&gt;crúbán claidhe&lt;/i&gt;&lt;/a&gt; term,
Dinneen's dictionary lists both "crab" and "frog" as possible translations of
&lt;i&gt;torpán&lt;/i&gt;.
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="ceann"&gt;&lt;i&gt;Ceanna-phiullan&lt;/i&gt;: usually used for tadpoles&lt;/h3&gt;
&lt;p&gt;&lt;span class=frog-intro&gt;&lt;i&gt;There was only one example of this being used for frogs, in Romasdal on
Skye. All other usages found were for tadpoles.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I wonder if this might be better written &lt;i&gt;ceann a' phiullan&lt;/i&gt;, or perhaps
more familiarly (to me) as &lt;i&gt;ceann a' phollain&lt;/i&gt;. To me this would seem to clearly
mean "head of the small pool". Dwelly (1918) equates &lt;i&gt;pollan&lt;/i&gt; to
&lt;i&gt;pollag&lt;/i&gt;, defined primarily as &lt;i&gt;little pool, hole, pit,
or pond&lt;/i&gt; (see also Macbain, 1911 who writes &lt;i&gt;ceann-phollag&lt;/i&gt; or
&lt;i&gt;ceann-phollan&lt;/i&gt; as words for tadpole).&lt;/p&gt;
&lt;p&gt;A fun comparison is a dialectal American English word for tadpole:
&lt;a href=https://en.wiktionary.org/wiki/polliwog#English&gt;"polliwog"&lt;/a&gt;.
Amusingly, the "poll" here means "head"! All together the word means "head
wiggle". In our Gaelic example we have "poll" to mean pool/pond, and another
word for head. Both would seem to refer to the tadpole as a little swimming
limbless head.&lt;/p&gt;
&lt;p&gt;It's harder to make sense of this term applying to frogs. I can't help but
wonder if the fieldworker who recorded this made an error!
&lt;a href=#toc&gt;&lt;small&gt;↩&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="other-words"&gt;Words not included in the map, and not discussed above&lt;/h2&gt;
&lt;h3 id="rannag"&gt;&lt;i&gt;Rannag&lt;/i&gt; on Man&lt;/h3&gt;
&lt;p&gt;The word &lt;i&gt;rannag&lt;/i&gt; seems to be the most popular word for
"frog" among Manx revivalists, but I was unable to find any attestations from
native speakers. The earliest extant occurrence seems to be in Fargher (1969):&lt;/p&gt;
&lt;blockquote&gt;
The common frog [...] is
&lt;u&gt;rannag&lt;/u&gt;, but this word became lost during the course of time
yet it was preserved in the place-name 'Poyll Ny Rannagyn' (pool
of the frogs). It is strange that this word is obviously connected with the
Latin name [&lt;i&gt;rana&lt;/i&gt;].
&lt;/blockquote&gt;

&lt;p&gt;No other mention of the placename "Poyll Ny Rannagyn" seems to be found in
other texts. The admission that &lt;i&gt;rannag&lt;/i&gt; had "become lost" suggests he had
never heard a native speaker use it. Doug Fargher, who was not a native
speaker, felt that the revitalisation of Manx required a revision of its
vocabulary (and grammar). This took the form of suggesting neologisms
"to meet modern needs" (Broderick, 2013)&lt;sup id="fnref:neologisms"&gt;&lt;a class="footnote-ref" href="#fn:neologisms"&gt;26&lt;/a&gt;&lt;/sup&gt;, and replacing "perceived
impurities or corruptions" used by native speakers with his own preferred words
(Lewin, 2017). The preface to Fargher's English-Manx dictonary states his
approach clearly (Fargher, 1979):&lt;/p&gt;
&lt;blockquote&gt;
The aim of this dictionary is purely practical. It is largely a prescriptive
work and not a descriptive one, that is to say, it does not aim to be a record
pure and simple of the language as it was spoken at any time during its
history, but tries to provide some sort of basic standard upon which to build
the modern Manx language of today and tomorrow, in order that those who feel
the need to express themselves in Manx may here find the necessary means to do
so.
&lt;/blockquote&gt;

&lt;p&gt;Although I take a more preservationist approach to my own Gaelic
learning, it is clear Fargher's work has played a significant part in the
revival of the language, which he dedicated much of his life to. See Lewin
(2016, 2017) for more exploration of Fargher's work's impact, context
and ideology.&lt;/p&gt;
&lt;p&gt;Back to &lt;i&gt;rannag&lt;/i&gt;. I admit my first instict was that Fargher might have
fabricated this word, but in the preface to his dictionary he openly admits he
"borrowed unashamedly from our Gaelic cousins" and "make[s] no apology
whatsoever for attempting to restore to the Manx language mutations, genders
and certain other characteristics of Gaelic which without doubt existed in
pre-literary and classical Manx but which had already disappeared before the
final demise of the native speakers"&lt;sup id="fnref:vandal"&gt;&lt;a class="footnote-ref" href="#fn:vandal"&gt;27&lt;/a&gt;&lt;/sup&gt;. Coyly commenting on the
strangeness of &lt;i&gt;rannag&lt;/i&gt;'s Latin root for a word he fabricated would seem
to be at odds with this open approach.&lt;/p&gt;
&lt;p&gt;In Lewin's work he uses "the term ‘Traditional Manx’ to refer to the now
extinct native variety deriving directly by intergenerational transmission from
earlier forms of Gaelic, and ‘Revived Manx’ for the variety spoken today,
predominantly as an L2 [second language]" (Lewin, 2017). The existence of the
latter is a joyous thing to me, but my work here on frogs is concerned with the
former, and in the absence of any evidence that the word "rannag" was ever used
in Traditional Manx, I have not included it in the map.&lt;/p&gt;
&lt;h3 id="uillichd"&gt;&lt;i&gt;Uillichd&lt;/i&gt; in Scotland&lt;/h3&gt;
&lt;p&gt;A curious word I found only in Forbes (1905) is &lt;i&gt;uillichd&lt;/i&gt; (it is also in
Dwelly, 1918, but sourced from Forbes). I believe this could have been
pronounced &lt;span class=ipa&gt;[ɯʎəçgʲ]&lt;/span&gt; though of course this is unattested
as I have found no other use of this word! I believe &lt;i&gt;uillic&lt;/i&gt; could have
the same pronounciation, but that would only suggest that frogs were called
some diminutive of "William", and the genitive at that (which does not make
sense to me grammatically). Perhaps this word is related to &lt;i&gt;ùill&lt;/i&gt; for oil
or grease, referring to the frog's mucusy skin. That is the best suggestion I
have. I wish I could find other usages!&lt;/p&gt;
&lt;h3 id="cruitín"&gt;&lt;i&gt;Cruitín díge&lt;/i&gt; in Oriel&lt;/h3&gt;
&lt;p&gt;Alongside &lt;i&gt;lúbán díge&lt;/i&gt;, discussed &lt;a href=#lúb&gt;above&lt;/a&gt;, O'Neill-Lane's dictionary lists
&lt;i&gt;cruitín díge&lt;/i&gt; as a word found in Oriel in Ireland. As well as the meaning
of "harp, lyre", Dinneen gives the meanings of "a hump on the back, a little
eminence; summit". Various sources from Monaghan and Cavan in The School's
Collection list "hump" as the meaning. I suppose once again our froggy friend
is being described as a little lump. The use of &lt;i&gt;díge&lt;/i&gt;, the genitive of
a word for "ditch", seems to have been common when referring to frogs in East Ulster.&lt;/p&gt;
&lt;!---

## Given names for the frog in stories and riddles

Gille Criosda Mhic Dhughail

Séan Ó Lupáin

Mac I Shliopán

Mach Uí Stíopháin

Seid (cos of the expanding when croaking) https://archive.org/details/witchcraftsecon01campgoog

---&gt;

&lt;h2 id="misc"&gt;Miscellaneous curiosities&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.reddit.com/r/CasualIreland/comments/184j053/anybody_that_lived_in_rural_ireland_remember_the/"&gt;"Anybody that lived in rural Ireland remember the frog man?"&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.oup.com/2024/03/a-jumping-frog-and-other-creatures-of-etymological-interest/"&gt;"A jumping frog and other creatures of etymological interest"&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.oup.com/2024/04/an-etymological-plague-of-frogs/"&gt;"An etymological plague of frogs"&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://centre-for-english-traditional-heritage.org/TraditionToday7/7Sayers_Toad.pdf"&gt;"The Etymology of English toad: Effects of the Celtic substrate?"&lt;/a&gt;
(strongly disagreed with by the previous item)&lt;/p&gt;
&lt;p&gt;&lt;a href="https://imuseum.im/search/collections/objects/mnh-museum-35823.html"&gt;A frog burned by a German bomb on the Isle of Man during World War
II&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://archive.org/details/annualreport04royauoft/page/29/mode/1up"&gt;Celtic etymology for the word "wilky" or "quilkin", used for frogs, from Cornish
&lt;i&gt;gwelsken&lt;/i&gt; meaning
"grass-skin"&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.nts.org.uk/stories/a-ribbiting-display"&gt;"A ribbiting display"&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="grma"&gt;Go rabh maith agaibh&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ciarán Ó Duibhín, ar ábhar misnigh é, agus as acmhainní ar líne a chur ar fáil&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dubhán Ó Longáin, as mo cheisteanna fá fhroganna a fhreagairt, agus as an
mhúinteoireacht&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Àdhamh Ó Broin, as d'obair ghoirt a roinnt, agus as labhairt fá fhroganna liom&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Christopher Lewin, for answering my questions about the possible origins of
the Manx word &lt;i&gt;rannag&lt;/i&gt;, and providing a copy of &lt;i&gt;The Manx Have a Word
for it, Book 4: Insects, Reptiles etc.&lt;/i&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Davis Sandefur agus Criostóir Ó Loingsigh, as &lt;i&gt;athadán&lt;/i&gt; a deánamh
  taighde, agus fá &lt;i&gt;laparán&lt;/i&gt; a insint domh&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ciarán Dunbar, as labhairt fá fhocla as Oirialla liom&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Màiri MacMillan, as labhairt fá fhroganna Uibhist liom&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Simon Thoumire, as sonraí teagmhála Mhàiri a thabairt domh&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Thank you to all the fieldworkers, the 1930s Irish schoolchildren, the
informants who took the time to be interviewed, and everyone who has ever gone
to the effort to make knowledge available online for others to access freely.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="orthography"&gt;Appendix: Orthography notes&lt;/h2&gt;
&lt;details&gt;
&lt;summary&gt;
Read more
&lt;/summary&gt;
&lt;br&gt;

When illustrating the words for frog above, I wondered whether I
should try to use a consistent orthography across the illustrations. The
writing systems used in Scotland and Ireland differ somewhat, having once been
shared, now are diverged. The Isle of Man's writing system was developed
independently and is very different, but the only word I've illustrated from
there is "frog", so the difference in orthography was not a concern.
&lt;br&gt;&lt;br&gt;

In the end, I have largely written the words in the illustrations as I would
expect to see them in the places they were recorded. I did, however, make some choices:
&lt;br&gt;&lt;br&gt;

&lt;ul&gt;

&lt;li&gt; When standard Irish orthography would have "sc" or "sp", I have written "sg"
  and "sb", as I believe is standard in Scotland (where I understand most
  surviving dialects have lost voicing contrast on plosives entirely). This is
  because I think the voicing of the second consonant is phonemically
  irrelevant in this context even in Ireland, as it is in English (compare
  "speech" with "sbeech"), and the (lack of) aspiration is what is most
  salient phonetically. Also the letter "g" looks nice in the font I chose, so
  this way we get to see it in &lt;i&gt;losgann&lt;/i&gt;.&lt;/li&gt;
&lt;br&gt;

&lt;li&gt;When there were a few variants of a word, the choice of which one to
    represent in the illustrations was a bit arbitrary.
    For example, although I had more attestations of &lt;i&gt;leumrachan&lt;/i&gt; than
    &lt;i&gt;leumachan&lt;/i&gt;,it seemed more convenient for the headword to be formulated simply from
    &lt;i&gt;leum&lt;/i&gt; + &lt;i&gt;achan&lt;/i&gt;, with further explanation of variants later
    on.&lt;/li&gt;
&lt;br&gt;

&lt;li&gt;This mostly applies to the datapoints on the map, but I have followed the old
  Scottish tradition of using "ó" for &lt;span class=ipa&gt;/oː/&lt;/span&gt; (as in
  &lt;i&gt;mór&lt;/i&gt; Eng. "big") and "ò" for &lt;span class=ipa&gt;/ɔː/&lt;/span&gt; (as in
  &lt;i&gt;òran&lt;/i&gt; Eng. "song").
&lt;/li&gt;

&lt;/ul&gt;

When adding datapoints to the map from written sources, I have always used the
written form from the source.

&lt;br&gt;&lt;br&gt;
When working from sources like the LASID that
provide phonetic transcriptions only, I have used a very loose phonetic
rendering in the orthography that is most familiar to me, which preserves
fortis-lenis contrast on L and N. Hence for LASID responses for the many areas
where this contrast is lost and only the lenis consonant remains, I have
written a single consonant character even if the standard spelling has a double
consonant, e.g. standard "froganna" has been rendered "froganaí" to represent
&lt;span class=ipa&gt;[frɑgəniː]&lt;/span&gt;. These spellings are really just here to make
the map easier to read, so please don't read too deeply into any of the choices
made in rendering the phonetic transcriptions as words.

&lt;/details&gt;

&lt;h2 id="bibles"&gt;Appendix: Frogs in Gaelic bibles&lt;/h2&gt;
&lt;details&gt;
&lt;summary&gt;Table of translations for "frog" in various Gaelic bibles 1602-1827&lt;/summary&gt;

&lt;br&gt;
The words vary in grammatical case. I believe the &lt;i&gt;-ibh&lt;/i&gt;
instances are dative plurals, and the rest nominative plurals.
The original Hebrew of Exodus
and Psalms uses the same word &lt;a href=https://biblehub.com/hebrew/6854.htm&gt;throughout&lt;/a&gt; for "frog".
&lt;br&gt;&lt;br&gt;

&lt;div class=table-container&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Year of edition&lt;/th&gt;
&lt;th&gt;Bible&lt;/th&gt;
&lt;th&gt;Exodus 8:2&lt;/th&gt;
&lt;th&gt;Exodus 8:3&lt;/th&gt;
&lt;th&gt;Exodus 8:4&lt;/th&gt;
&lt;th&gt;Exodus 8:5&lt;/th&gt;
&lt;th&gt;Exodus 8:6&lt;/th&gt;
&lt;th&gt;Exodus 8:7&lt;/th&gt;
&lt;th&gt;Exodus 8:8&lt;/th&gt;
&lt;th&gt;Psalms 78:45&lt;/th&gt;
&lt;th&gt;Psalms 105:30&lt;/th&gt;
&lt;th&gt;Revelation 16:13&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1602&lt;/td&gt;
&lt;td&gt;&lt;a href="https://archive.org/details/bim_early-english-books-1475-1640_tiomna-nuadh-ar-d-tighea_bible-nt-irish_1602/mode/2up"&gt;New Testament translation by various Irish-born Church of Ireland priests&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguibh&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1685&lt;/td&gt;
&lt;td&gt;&lt;a href="http://corpas.ria.ie/index.php?fsg_function=3&amp;amp;fsg_id=2405"&gt;Old Testament translation by English bishop William Bedell&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguibh&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisgionn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisghionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1690&lt;/td&gt;
&lt;td&gt;&lt;a href="https://archive.org/details/bim_early-english-books-1641-1700_an-biobla-naomhtha-iona_bible-gaelic_1690/page/n59/mode/2up"&gt;(as above)&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguibh&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguide&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froguidhe&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisgionn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisghionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1817&lt;/td&gt;
&lt;td&gt;&lt;a href="https://archive.org/details/GLEBED_DBS_HS/page/59/mode/2up"&gt;(as above)&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;lúisgionn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;cnadáin&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisgionn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisgionn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;cnadáin&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;cnadáin&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisgionn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisgionn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisgionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1827&lt;/td&gt;
&lt;td&gt;&lt;a href="https://archive.org/details/leabhuirtseantio00bede/page/68/mode/2up"&gt;(as above)&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;lúisgionn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;lúisgionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisgionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;lúisgionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;lúisgionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;lúisgionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;lúisgionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;luisgion&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;lúisgionna&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1767&lt;/td&gt;
&lt;td&gt;&lt;a href="https://digital.nls.uk/rare-items-in-gaelic/archive/97180274"&gt;New Testament translation by James Stewart and Dugald Buchanan, both Scottish&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;losguinn&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1801&lt;/td&gt;
&lt;td&gt;&lt;a href="https://digital.nls.uk/rare-items-in-gaelic/archive/102328331"&gt;Old Testament translation by John Stewart of Luss, son of James Stewart above&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;losgannaibh&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;losgainn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;losgainn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;losgannaibh&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;losgainn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;losgainn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;losgain&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1610&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.academia.edu/41457167/Phillips_Manx_translation_of_the_Psalms_MNH_MS_00003_Corrected"&gt;Manx translation of Psalms by John Phillips, born in Wales and educated at Oxford&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;ffroggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;ffroggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1775&lt;/td&gt;
&lt;td&gt;&lt;a href="https://manx.global.bible/bible/3a7d2caa4b5b4bec-01/PSA.105"&gt;Manx bible, led by English bishop Mark  Hildesley, with assistance from Manx scholar John Kelly&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;froggyn&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/details&gt;

&lt;h2 id="bibliography"&gt;Bibliography&lt;/h2&gt;
&lt;p&gt;Sources only cited in the datapoints are either directly cited there, or are
listed in the introduction (e.g. the LASID). They are not listed here.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Broderick, G. (2013). &lt;a href="https://journal.fi/scf/article/download/7663/14658/40703"&gt;&lt;i&gt;Neologisms in Revived Manx
  Gaelic&lt;/i&gt;&lt;/a&gt;. Studia Celtica Fennica: 7–29.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cambrensis, G. (1863). &lt;a href="https://www.yorku.ca/inpar/topography_ireland.pdf"&gt;&lt;i&gt;The Topography of Ireland&lt;/i&gt; (T. Forester, Trans.)
&lt;/a&gt;. London : H.G. Bohn
(Original work published c. 1188)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Carmichael, A. (1928). &lt;a href="https://www.electricscotland.com/books/pdf/carminagadelicah02carm.pdf"&gt;&lt;i&gt;Carmina
  Gadelica, Volume II&lt;/i&gt;&lt;/a&gt;.  Edinburgh : Tweeddale Court&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clague, J. (1911). &lt;a href="https://corpus.gaelg.im/docs/Cooinaghtyn-Manninagh?q=frog"&gt;&lt;i&gt;Cooinaghtyn
  Manninagh&lt;/i&gt;&lt;/a&gt;.
  Castletown : M. J. Blackwell.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cormac (pseudonym) (1909). &lt;i&gt;Frog&lt;/i&gt;. An Claidheamh Soluis 11:9 (8/5/1909).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;De Bhaldraithe, T. (1945). &lt;i&gt;Gaeilge Chois Fhairrge: An Deilbhíocht&lt;/i&gt;.
  Dublin : Institute of Advanced Studies.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;De Bhaldraithe, T. (1985). &lt;i&gt;Foirsiún Focal as Gaillimh&lt;/i&gt;. Dublin :
  Acadamh Ríoga na hÉireann.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;de Rochefort, A. J. (1779). &lt;a href="https://celt.ucc.ie/published/T100075/text005.html"&gt;&lt;i&gt;Albert Jouvin, de Rochefort, Description of
  Ireland after the
  Restoration&lt;/i&gt;&lt;/a&gt;. In
  Francis Grose and Thomas Astle (eds.), &lt;i&gt;Antiquarian Repertory&lt;/i&gt;, London :
  for E. Jeffrey. (Original work published 1672)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dinneen, P. S. (1904). &lt;a href="https://archive.org/details/foclirgaeilgeagu00dinn"&gt;&lt;i&gt;Foclóir Gaedhilge agus
  Béarla&lt;/i&gt;&lt;/a&gt;. Irish  Texts
  Society. (also referred to as "Dinneen's dictionary")&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dorian, N. C. (1978). &lt;i&gt;East Sutherland Gaelic: the dialect of the Brora,
  Golspie, and Embo fishing communities&lt;/i&gt;. Dublin : Dublin Institute of
  Advanced Studies.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dorian, N. C. (1981). &lt;i&gt;Language Death: Life Cycle of a Scottish Gaelic
  Dialect&lt;/i&gt;. University of Pennsylvania Press Anniversary Collection.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dubourdieu, J. (1802).
  &lt;a href="https://archive.org/details/statisticalsurve00duboiala/page/315/mode/1up"&gt;&lt;i&gt;Statistical survey of the County of
  Down&lt;/i&gt;&lt;/a&gt;.
  Dublin : Graisberry and Campbell.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dunbar, C. (2025). &lt;a href="https://www3.smo.uhi.ac.uk/oduibhin/leabharthai/CNUASACH%20FOCAL%20AS%20ORIALLA%20leagan%201.1%201025.pdf"&gt;&lt;i&gt;Cnuasach Focal as
  Oirialla&lt;/i&gt;&lt;/a&gt;.
  [Online edition]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dwelly, E. (1918). &lt;a href="https://archive.org/details/illustratedgaeli01dweluoft/page/n7/mode/2up"&gt;&lt;i&gt;The illustrated Gaelic
  dictionary&lt;/i&gt;&lt;/a&gt;.
  Fleet, Hampshire : The author.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fargher, D. C. (1969). &lt;i&gt;The Manx have a word for it, Book 4: Insects,
  Reptiles, etc.&lt;/i&gt;. Reayrt Ny Marrey : The author.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fargher, D. C. (1979). &lt;i&gt;Fargher's English-Manx Dictionary&lt;/i&gt;. Douglas : Shearwater Press&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Beckett, C. (1967). &lt;i&gt;Fealsúnacht Aodha Mhic Dhomhnaill&lt;/i&gt;. Baile Átha
  Cliath : An Clóchomhar Tta. (Original manuscript 1853)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Forbes, A. R. (1905). &lt;a href="https://archive.org/details/gaelicnamesofbea00forb/page/406/mode/2up"&gt;&lt;i&gt;Gaelic names of beasts (Mammalia), birds, fishes,
  insects, reptiles, etc.&lt;/i&gt;&lt;/a&gt;.
  Edinburgh : Oliver and Boyd : Norman Macleod.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hamilton, J. N. (1974). &lt;a href="https://www3.smo.uhi.ac.uk/oduibhin/leabharthai/The%20Irish%20of%20Tory%20Island%20-%20Hamilton.pdf"&gt;&lt;i&gt;A phonetic study of the Irish of Tory Island, Co.
  Donegal&lt;/i&gt;&lt;/a&gt;.
  Belfast : Institute of Irish Studies, Queen's University Belfast&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Henry, S. (1939). &lt;i&gt;The Cinderella of Rathlin Island&lt;/i&gt;. The Belfast
  Telegraph (18/04/1939)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Holmer, N. M. (1942). &lt;i&gt;The Irish Language in Rathlin Island, Co.
  Antrim&lt;/i&gt;. Dublin : Royal Irish Academy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kelly, J. (1866). &lt;a href="https://archive.org/details/cu31924027086945"&gt;&lt;i&gt;The Manx
  Dictionary&lt;/i&gt;&lt;/a&gt;. Douglas : The
  Manx Society&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lewin, C. (2016). &lt;a href="https://www.academia.edu/39715888/The_revivability_of_Manx_Gaelic_a_linguistic_description_and_discussion_of_Revived_Manx"&gt;&lt;i&gt;The revivability of Manx Gaelic: a linguistic
  description and discussion of Revived
  Manx&lt;/i&gt;&lt;/a&gt;. Aberystwyth University.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lewin, C. (2017). &lt;a href="https://reference-global.com/article/10.1515/scp-2017-0006"&gt;&lt;i&gt;Scholarship and language revival:
  language ideologies in corpus development for Revived
  Manx&lt;/i&gt;&lt;/a&gt;. Studia Celtica Posnaniensia, 2(1), 97–118.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Macbain, Alexander (1911). &lt;a href="https://archive.org/details/etymologicaldict00macbuoft/page/232/mode/2up"&gt;&lt;i&gt;An Etymylogical Dictionary of the Gaelic
  Language&lt;/i&gt;&lt;/a&gt;. Stirling : Eneas Mackay.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Marstrander, C. (1908). &lt;a href="https://archive.org/details/sprogligeoghist00olsegoog/page/n258/mode/2up"&gt;&lt;i&gt;Über irisches loscann und einige andere
  indogermanische Namen der
  kröte&lt;/i&gt;&lt;/a&gt;.
  In Magnus Bernhard Olsen (ed.), &lt;i&gt;Sproglige og historiske afhandlinger viede
  Sophus Bugges minde&lt;/i&gt;, 240-246. Oslo : H. Aschehoug &amp;amp; Co.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mac Giolla Chearna, P. (1940). &lt;i&gt;Ceachta as Leabhar na Cruinne&lt;/i&gt;. Baile
  Átha Cliath : Oifig an tSoláthair.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mac Gréagóir, A. (1908). &lt;i&gt;Sean-Ranna Ultacha&lt;/i&gt;. An Claidheamh Soluis
10:15 (20/6/1908). [under the pen-name &lt;i&gt;Gréagóirína Nic Gréagóir Gréagach&lt;/i&gt;]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mac Gréagóir, A. (1910). &lt;a href="https://www3.smo.uhi.ac.uk/oduibhin/leabharthai/Sg%C3%A9altan%20Rachreann.pdf"&gt;&lt;i&gt;Sgéaltan X
  Rachreann&lt;/i&gt;&lt;/a&gt;. Gill, M. H. &amp;amp; a Mhac Teor.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mac Meanman, S. (1940). &lt;i&gt;Crann an Eolais, An Toradh&lt;/i&gt;. Dublin : Brún agus Ó
Nualláin Teór.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;McKenna, L. (1947). &lt;i&gt;Book of Magauran: Leabhar Méig Shamhradháin&lt;/i&gt;.
  Dublin : Dublin Institute for Advanced Studies. [HTML version]. Retrieved
  from
  &lt;a href="https://celt.ucc.ie/published/G402561/header.html"&gt;https://celt.ucc.ie/published/G402561/header.html&lt;/a&gt;.
  (Original manuscript 1330s)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;O'Clery, M., &amp;amp; Miller, A. W. K. (1883). &lt;a href="https://deriv.nls.uk/dcn23/8177/81776163.23.pdf"&gt;&lt;i&gt;O'Clery's Irish glossary: Printed
  at Louvrain in 1643.
  s.n.&lt;/i&gt;&lt;/a&gt;. Revue Celtique,
  5 (1881-1883). 16. (Original work published 1643 as &lt;i&gt;Foclóir nó Sanasán
          Nua&lt;/i&gt;) (also referred to as "O'Clery's glossary")&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ó Dónaill, N. (1977). &lt;i&gt;Foclóir Gaeilge–Béarla&lt;/i&gt;. Dublin: An Gúm&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;O'Fothartha, D. (1892). &lt;a href="https://babel.hathitrust.org/cgi/pt?id=uc1.c070984047&amp;amp;seq=139"&gt;&lt;i&gt;Siamsa an gheimhridh: no Cois an teallaigh in Iar
  gConnachta&lt;/i&gt;&lt;/a&gt;.
  Baile Átha Cliath : O'Brien Patrick&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mac Aingil, A. (1952). &lt;a href="http://corpas.ria.ie/index.php?fsg_function=3&amp;amp;fsg_id=2344"&gt;&lt;i&gt;Scáthán Shacramuinte na
  hAithridhe&lt;/i&gt;&lt;/a&gt;
  (C. Ó Maonaigh, Trans.).
  Dublin : Dublin Institute for Advanced Studies. (Original work 1618)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;O'Neill-Lane, T. (1917). &lt;a href="https://archive.org/details/largerenglishiri00onei/page/n3/mode/2up"&gt;&lt;i&gt;Larger English-Irish
  Dictionary&lt;/i&gt;&lt;/a&gt;.
  New York : Funk &amp;amp; Wagnalls Co.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;O'Reilly, E. (1864). &lt;a href="https://archive.org/details/anirishenglishd00odogoog"&gt;&lt;i&gt;An Irish-English dictionary&lt;/i&gt;&lt;/a&gt;. Dublin : James Duffy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quiggin, E. C. (1906). &lt;a href="https://en.wikisource.org/wiki/A_Dialect_of_Donegal"&gt;&lt;i&gt;A Dialect of Donegal&lt;/i&gt;&lt;/a&gt;. Cambridge : University Press.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Robertson, C. M. (1898). &lt;a href="https://archive.org/details/transactionsgae06unkngoog/page/n76/mode/2up"&gt;&lt;i&gt;Skye
  Gaelic&lt;/i&gt;&lt;/a&gt;.
  In: Transactions of The Gaelic Society of Inverness, 23 (1898-1899). 54-89&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Robertson, C. M. (1900). &lt;a href="https://archive.org/details/transactionsvol00invegoog/page/320/mode/2up&amp;gt;"&gt;&lt;i&gt;The Gaelic of the West of
  Ross-shire&lt;/i&gt;&lt;/a&gt;.
  In: Transactions of The Gaelic Society of Inverness, 24 (1899-1901). 321-69&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scharff, R. F. (1893).
  &lt;a href="https://archive.org/details/irishnaturalist02roya/page/n17/mode/2up"&gt;&lt;i&gt;Is The Frog a Native of Ireland?&lt;/i&gt;&lt;/a&gt;.
  The Irish Naturalist, 2(1), 1–6.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scouller, A. M. (2018). &lt;a href="https://era.ed.ac.uk/server/api/core/bitstreams/c5b70130-aec4-4f11-b6f6-60f3fd8263cf/content"&gt;&lt;i&gt;The Gaelic Dialect of
  Colonsay&lt;/i&gt;&lt;/a&gt;.
  The University of Edinburgh&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sinclair, A. (1879). &lt;a href="https://archive.org/details/gaelicsongstertr00sinc/page/n4/mode/1up"&gt;&lt;i&gt;The Gaelic
  songster&lt;/i&gt;&lt;/a&gt;.
  Glasgow : The author.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sjoestedt, M. L. (1930). &lt;a href="https://fr.wikisource.org/wiki/Phon%C3%A9tique_d%E2%80%99un_parler_irlandais_de_Kerry/2-6#p163"&gt;&lt;i&gt;Phonétique d’un parler irlandais de
  Kerry&lt;/i&gt;&lt;/a&gt;.
  In: Annales de Bretagne. Book 40, number 3, 1932. 570-571&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stewart, A. (1885). &lt;a href="https://dn720005.ca.archive.org/0/items/twixtbennevisgle00stew_1/twixtbennevisgle00stew_1.pdf"&gt;&lt;i&gt;Twixt Ben Nevis and
  Glencoe&lt;/i&gt;&lt;/a&gt;. Edinburgh : W. Paterson&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stockman, G. (1974). &lt;a href="https://www3.smo.uhi.ac.uk/oduibhin/leabharthai/Stockman%20(1974),%20The%20Irish%20of%20Achill,%20Co%20Mayo.pdf"&gt;&lt;i&gt;The Irish of Achill, Co.
  Mayo&lt;/i&gt;&lt;/a&gt;. Belfast : Institute of Irish Studies, Queen's University of Belfast.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Wentworth, R. (1993). &lt;a href="https://www3.smo.uhi.ac.uk/gaidhlig/wentworth/faclair/dualchainnt/"&gt;&lt;i&gt;Faclan is Abairtean à Ros an
  Iar&lt;/i&gt;&lt;/a&gt;. Clar.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Whitfield, N. (1994). &lt;a href="https://www.academia.edu/19143240/My_Grandfather_Dr_S%C3%A9amus_%C3%93_Ceallaigh_1879_1954_in_Graham_Mawhinney_ed_Gleanings_from_Ulster_History_by_S%C3%A9amus_%C3%93_Ceallaigh_1879_1954_2nd_ed_Ballinascreen_Historical_Society_1994_iii_xxx"&gt;&lt;i&gt;My Grandfather , Dr. Séamus Ó Ceallaigh
  (1879-1954)&lt;/i&gt;&lt;/a&gt;.
  In &lt;i&gt;Gleanings from Ulster History&lt;/i&gt;, iii-xxiii. Draperstown :
  Ballinascreen Historical Society. (Reprint of 1951 publication with new
  introductory material)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Dorian (1981) p. 101: &lt;blockquote&gt;Precisely because everyone
uses such loanwords, and because there is considerable self-consciousness about
it, the number of loanwords in a verbal performance seems to have become a
marker of degree of formality in ESG [East Sutherland Gaelic]. In a relaxed and
casual performance, the number of lexical borrowings will rise [...] the more
formal the performance &amp;mdash; for example, established narrative routines
reproduced for tape recording &amp;mdash; the lower the number of lexical
borrowings [...] &lt;/blockquote&gt; She gives an example of a tape-recorded
narrative, where a speaker replaced the borrowing of
&lt;i&gt;poileas&lt;/i&gt; ("police") with &lt;i&gt;luchd an lagh&lt;/i&gt; ("law people"). Dorian
notes this as "elegant Gaelic but otherwise foreign to the lips of any East
Sutherlander of my acquaintance". This correlation of formality and
loan-word occurrence may be less prevelant in areas with healthier Gaelic. The
subjects in the above were of the last couple generations of speakers of a
dialect particularly far removed from what was considered standard (which
negatively affected some, though not all, of the speakers' perception of the legitimacy of their
Gaelic), and were subject to mockery from English monolinguals for
their loanword usage. In a healthier community of speakers I imagine loanwords
might be used more confidently and less self-consciously.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Something I learnt during this project was that the distinction between
frogs and toads is considered part of a folk taxonomy, not precisely aligned
with scientific classification. Yet the common frog (&lt;i&gt;rana temporaria&lt;/i&gt;)
and common toad (&lt;i&gt;bufo bufo&lt;/i&gt;) are in different genera, and my reading
tells me members of &lt;i&gt;rana&lt;/i&gt; are generally wartless, and are all good
jumpers. Perhaps in these islands, where we have very few species, it does at
least line up with scientific taxonomy. In other parts of the world with more
amphibious diversity it seems there is more variation on whether folk and
scientific taxonomies align.&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:fròg"&gt;
&lt;p&gt;Dwelly (1918) p. 457: "1. Hole, chink, niche, nook, cranny. 2. marsh,
fen" for &lt;i&gt;fròg&lt;/i&gt;. O'Reilly (1864) p. 259: "a fen,
a marsh ; a pitfall, a hole, a cleft;" for &lt;i&gt;frog&lt;/i&gt; (before also giving
the animal). The marsh and hole senses seem to have
left Ireland. Dwelly gives "active, energetic" for &lt;i&gt;frog&lt;/i&gt;, a meaning I
haven't seen in any Irish texts.&amp;#160;&lt;a class="footnote-backref" href="#fnref:fròg" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:omens"&gt;
&lt;p&gt;You can download a CSV of my collected list
&lt;a href="../static/froganna/data/omens.csv"&gt;here&lt;/a&gt;. The list is not exhaustive and was
collected by searching the NFC for "frog luck", "frog omen", "frog house",
"frog death", "frog bás", "frog good". A common belief stated was that killing
a frog would bring you bad luck, but this doesn't really signal anything of the
nature of a chance encounter with a frog. Similarly lore that described the
frog as blessed in some way was not included; indeed, one of the pieces of lore
that stated frogs in the house is an omen of death said this is because frogs
are considered "blessed". Being blessed does not equal being looked upon
without fear.&lt;br&gt;&lt;br&gt;My favourite piece of lore found during this search
was &lt;a
href=https://www.duchas.ie/en/cbes/4921682/4889594/4951820&gt;this&lt;/a&gt;
one:&lt;blockquote&gt;The frog was looked upon as something sacred as it was the frog
taught Our Lord how to swim.&lt;/blockquote&gt;Did he now...&amp;#160;&lt;a class="footnote-backref" href="#fnref:omens" title="Jump back to footnote 4 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:scharff"&gt;
&lt;p&gt;Scharff (1893).  This article explores various historical accounts of
frogs being found in Ireland, including Gerard of Wales's. The idea that
Trinity students introduced frogs is dismissed by the author for being
ecologically unlikely, noting that there are far more frogs on the west coast
and the city doesn't seem like an ideal place for frogs to thrive.&amp;#160;&lt;a class="footnote-backref" href="#fnref:scharff" title="Jump back to footnote 5 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:orange"&gt;
&lt;p&gt;O'Reilly (1864) p. 259 states the frog is "an animal not found in Ireland
before the reign of William the Third of England, whose Dutch troops first
introduced it amongst us".&amp;#160;&lt;a class="footnote-backref" href="#fnref:orange" title="Jump back to footnote 6 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:down"&gt;
&lt;p&gt;Dubourdieu (1802) pp. 315-316: "that [frogs] first made their
appearance near Moira, in the western parts of this county, can be
proved beyond contradiction" but declines to do so himself. He
offers an anecdote from a local man about when he first seen a frog.&amp;#160;&lt;a class="footnote-backref" href="#fnref:down" title="Jump back to footnote 7 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:gerard-date"&gt;
&lt;p&gt;I have &lt;a
href=https://www.dib.ie/biography/gerald-wales-giraldus-cambrensis-a3490&gt;read&lt;/a&gt;
       that Gerard first visited Ireland in 1183, and &lt;i&gt;Topographia
Hibernia&lt;/i&gt;, containing the account, was circulated in 1188. However, he mentions Robert Poer in the
account, who I read &lt;a href=https://www.dib.ie/biography/poer-robert-a7399&gt;died&lt;/a&gt; in
1178. The Ossory king in question is said to have died in 1185.&amp;#160;&lt;a class="footnote-backref" href="#fnref:gerard-date" title="Jump back to footnote 8 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:topographia"&gt;
&lt;p&gt;Cambrensis (1863)&amp;#160;&lt;a class="footnote-backref" href="#fnref:topographia" title="Jump back to footnote 9 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:king"&gt;
&lt;p&gt;Domnall Mac Gilla Pátraic, see this &lt;a
href=https://www.dib.ie/biography/poer-robert-a7399&gt;biography&lt;/a&gt; of Robert Poer&amp;#160;&lt;a class="footnote-backref" href="#fnref:king" title="Jump back to footnote 10 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:licking"&gt;
&lt;p&gt;I think people thought frogs to be very absorbent, hence their ability
to remove aches and pains through touch. I don't personally interpret this
belief as necessarily attributing mystical powers to the frog. The other Manx sources consulted were 
&lt;a href="https://corpus.gaelg.im"&gt;The Manx Corpus&lt;/a&gt; (containing Clauge, 1911);
Sophia Morrison's 1911 &lt;a href=https://archive.org/details/manxfairytales00morr/page/n15/mode/2up&gt;&lt;i&gt;Manx
Fairy Tales&lt;/i&gt;&lt;/a&gt; where I found no mention of frogs; &lt;i&gt;Skeealyn
Cheeil-Chiollee&lt;/i&gt;, edited by Stephen Miller and published in 1993, containing
folklore collected by Charles Roeder in the last quarter of the 19th century,
and where I found no mention of frogs.&amp;#160;&lt;a class="footnote-backref" href="#fnref:licking" title="Jump back to footnote 11 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:leprosy"&gt;
&lt;p&gt;The spelling &lt;i&gt;loscann&lt;/i&gt; is used
&lt;a href="https://www.duchas.ie/en/cbes/4427982/4363624/4467633?HighlightText=loscann&amp;amp;Route=stories&amp;amp;SearchLanguage=ga"&gt;here&lt;/a&gt;
to mean "burning", as a variant of standard &lt;i&gt;loisceann&lt;/i&gt;. I think the only
other proposed etymology I've seen is in Carmichael, 1928, p. 332:
"Probably the toad is called 'losgan' from 'losg' irruption, leprosy". This
seems much less likely to me, based on the various sources found via the eDIL,
than the &lt;i&gt;loiscend&lt;/i&gt; derivation. I believe the word given for leprosy
mostly referred to &lt;a href=https://dil.ie/30704&gt;lameness&lt;/a&gt; (which can
be a secondary effect of leprosy). I'm not sure what toads would have to
do with leprosy; perhaps their bumpy skin was thought to be reminiscent
of leprosy nodules. I have seen it suggested that &lt;a
href=https://en.wikipedia.org/wiki/Taddiport&gt;Taddiport&lt;/a&gt;, a leper
colony in the Middle Ages, was named so because of this. I haven't found
much on toads being used to refer to people suffering from leprosy at the
time, however, but I only looked briefly.&amp;#160;&lt;a class="footnote-backref" href="#fnref:leprosy" title="Jump back to footnote 12 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:dragon"&gt;
&lt;p&gt;&lt;i&gt;Comhrag losguinn lasrach mear ná sir—is sé do dhaingean—suail a sheadh
i n-armaibh áigh, marbhaidh fear uaidh dá anáil.&lt;/i&gt; The text refers to a
creature &lt;losguinn&gt; breathing fire.&amp;#160;&lt;a class="footnote-backref" href="#fnref:dragon" title="Jump back to footnote 13 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:cricket"&gt;
&lt;p&gt;See this &lt;a href="https://anglo-norman.net/entry/salemandre"&gt;entry&lt;/a&gt; in an
Anglo-Norman dictionary, and this blog post &lt;a href="https://grammarphobia.com/blog/2021/07/cricket-croquet.html"&gt;"Not quite
cricket?"&lt;/a&gt; from
Grammarphobia.
&lt;a href="https://quod.lib.umich.edu/m/middle-english-dictionary/dictionary/MED10321"&gt;This&lt;/a&gt;
Middle English dictionary shows the converse, &lt;i&gt;criket&lt;/i&gt;
being used to refer to the fire lizard. Thank you to Grammarphobia for sharing
the OED extracts.&amp;#160;&lt;a class="footnote-backref" href="#fnref:cricket" title="Jump back to footnote 14 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:synonyms"&gt;
&lt;p&gt;I wondered if perhaps the synonyms listed in O'Clery's glossary can
provide more clues. &lt;i&gt;Cú cnámha&lt;/i&gt; appears to read as "hound of
bones", though the eDIL &lt;a href=https://dil.ie/13291&gt;tells us&lt;/a&gt; that
&lt;i&gt;cú&lt;/i&gt; has also been generically used for creatures, particularly insects.
In Forbes (1905) this word is cited as meaning
"louse", as is the other synonym listed by O'Clery, &lt;i&gt;snasán&lt;/i&gt;.  I
suppose, like salamanders, you might expect to find woodlice in your
firewood, if you kept it outside. But these words could easily be referring to
crickets also. In the end these synonyms mostly increase my confidence that the
glossary is referring to crickets, not to salamanders the lizards. Whether the
usage for frogs evolved from the usage for crickets, or alongside it, will
remain a mystery.&amp;#160;&lt;a class="footnote-backref" href="#fnref:synonyms" title="Jump back to footnote 15 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:liospán"&gt;
&lt;p&gt;Thank you to Gerry Oates' article &lt;i&gt;An phéist a chuir an cluiche
ar Phádraig&lt;/i&gt; in &lt;i&gt;An tUltach&lt;/i&gt; which directed me to this, via the
National Corpus of Irish. Mac Giolla Ceara, 1940, p. 42: "An préachán dubh ar
an chrann, an traona san choirce, agus an liospán san pholl [...]"&amp;#160;&lt;a class="footnote-backref" href="#fnref:liospán" title="Jump back to footnote 16 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:granny"&gt;
&lt;p&gt;This was the school my granny went to :) and my granda's parents etc.&amp;#160;&lt;a class="footnote-backref" href="#fnref:granny" title="Jump back to footnote 17 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:locha"&gt;
&lt;p&gt;The schoolchild actually wrote &lt;i&gt;lisbín lacha&lt;/i&gt;, which I don't
think makes grammatical sense (&lt;i&gt;lacha&lt;/i&gt; is the nominative case of the word
meaning "duck", but the genitive would be needed here. An association
with ducks (the animals) makes a lot less sense than with bodies of
water). So I assume this was a spelling error on the child's part.&amp;#160;&lt;a class="footnote-backref" href="#fnref:locha" title="Jump back to footnote 18 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:welsh-leum"&gt;
&lt;p&gt;In Welsh, the cognate &lt;i&gt;llam&lt;/i&gt; gives us
&lt;i&gt;llamhidydd&lt;/i&gt;, similarly meaning "jumper" and used for porpoises.&amp;#160;&lt;a class="footnote-backref" href="#fnref:welsh-leum" title="Jump back to footnote 19 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:cnádán-bible"&gt;
&lt;p&gt;The introduction of this bible says that the Old Testament
is translated by William Bedell and "some changes made from the edition of
1690". I assume one of the changes was changing to use &lt;i&gt;cnadáin&lt;/i&gt;, though
only in some places. See the &lt;a href=#bibles&gt;appendix on Gaelic bibles&lt;/a&gt; for a full table of frog
words used in bible editions.&amp;#160;&lt;a class="footnote-backref" href="#fnref:cnádán-bible" title="Jump back to footnote 20 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:s-mobile"&gt;
&lt;p&gt;All of my knowledge of this comes from noticing the parenthesised
"s" in PIE derivations, and
&lt;a href="https://en.wikipedia.org/wiki/Indo-European_s-mobile"&gt;this&lt;/a&gt; Wikipedia article.&amp;#160;&lt;a class="footnote-backref" href="#fnref:s-mobile" title="Jump back to footnote 21 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:body-parts"&gt;
&lt;p&gt;It's common for body parts (and animals) to be used in
placenames to describe geographical features. E.g. &lt;i&gt;droim&lt;/i&gt; "back" used for
"ridge".&amp;#160;&lt;a class="footnote-backref" href="#fnref:body-parts" title="Jump back to footnote 22 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:crabfish"&gt;
&lt;p&gt;"Crabfish" also meant lobster, but the LASID universally gives
&lt;i&gt;gliomach&lt;/i&gt; (&lt;i&gt;giomach&lt;/i&gt; in Scotland) for that.&amp;#160;&lt;a class="footnote-backref" href="#fnref:crabfish" title="Jump back to footnote 23 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:rathlin"&gt;
&lt;p&gt;The word &lt;i&gt;crúbán&lt;/i&gt; is used in the Rathlin retelling of
Cinderella recorded in Mac Gréagóir (1910).
This is translated in the Belfast Telegraph 18/04/1939
by Sam Henry and titled "The Cinderella of Rathlin Island", where &lt;i&gt;crúbán&lt;/i&gt;
seems to be translated as "pig's feet" &amp;mdash; however, I don't think this
translation is trustworthy. Ciarán Ó Duibhín thinks Sam Henry likely didn't have much
Irish, let alone knowledge of Rathlin's dialect. It
&lt;a href="https://niarchive.org/wp-content/uploads/2020/03/Sam-Henry-Booklet-WR.pdf"&gt;seems&lt;/a&gt; schoolteacher Andrew
Dooey often did translation for him.&lt;br&gt;&lt;br&gt;Onto the usage of &lt;i&gt;crúbán&lt;/i&gt; in the
Cinderella telling. There's not a huge
amount of context. First we are told of her sisters' activities: &lt;blockquote&gt;Tosuigh iad ag gearradh a saltann is luiríní móra daoibh ag
feitheamh an bheireochadh an bróg carnóg sin orra&lt;/blockquote&gt;I think
&lt;i&gt;saltann&lt;/i&gt; is "heels (n.)", given as &lt;i&gt;sáltan&lt;/i&gt; in Holmer (1942). I
think &lt;i&gt;luiríní&lt;/i&gt; refers to digits, in this case toes, some kind of
diminutive of &lt;i&gt;ladhar&lt;/i&gt;. The word is also used in another story in the same
collection where it seems to be referring to fingers. Ciarán has glossed it as
"toes" in his East Ulster Dictionary. So I believe this
describes the sisters cutting their heels and toes in order to fit into the
shoe. Cinderella is then forced to hide under a tub while the prince visits.
She cries out: &lt;blockquote&gt;&lt;i&gt;Saltann móra lobhtha&lt;br&gt;
Is ['s = agus] ladhra gearrtha crúbán&lt;br&gt;
Is ['s = agus] an té beag buidheach &lt;/i&gt;[Cinderella]&lt;i&gt;&lt;br&gt;
Síos faoi an tubhán&lt;/i&gt;&lt;/blockquote&gt;
Perhaps this is "Big rotten heels and cut crab claws, and the little yellow one
[referring to Cinderella] under the tub". It was not easy for me to arrive at
this translation. &lt;i&gt;Lobhtha&lt;/i&gt; is "rotten" (modern spelling &lt;i&gt;lofa&lt;/i&gt;). We
already have &lt;i&gt;saltann&lt;/i&gt; as "heels" above.
I assumed &lt;i&gt;ladhra&lt;/i&gt; is the nominative plural of &lt;i&gt;ladhar&lt;/i&gt; for
toes/claws. And I am assuming &lt;i&gt;crúbán&lt;/i&gt; is genitive plural of
&lt;i&gt;crúbán&lt;/i&gt;. The use of &lt;i&gt;ladhar&lt;/i&gt;, which can mean both toes (Holmer,
1942) and claws (Ó Dónaill, 1977) right after talking about the sisters cutting
their toes made me assume she was still talking about her sister's toes. But
I can't reconcile that with the use of &lt;i&gt;crúbán&lt;/i&gt;.&lt;br&gt;&lt;br&gt;
Thank you to Ciarán Ó
Duibhín for helping me with this translation. I did not twig (did you know twig
is from &lt;i&gt;tuig&lt;/i&gt;?) that &lt;i&gt;is&lt;/i&gt; probably wasn't the copula here, but
a shortened form of &lt;i&gt;agus&lt;/i&gt; ("and") that I have usually seen rendered
&lt;i&gt;'s&lt;/i&gt;. I also forgot that the genitive plural is identical to the
nominative singular for first declension nouns with weak plurals. These two
oversights meant I could make no sense of it, despite having identified the
meaning of the nouns. Go rabh maith agad a chara.&amp;#160;&lt;a class="footnote-backref" href="#fnref:rathlin" title="Jump back to footnote 24 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:riddle"&gt;
&lt;p&gt;It is interesting comparing this 1892 recording of the riddle with
versions from the The Schools' Collection (1930s) and the LASID (1950s). Most of
the later versions are significantly truncated, with all except one missing the first line
and some missing enough that it evokes a child making a barely passable
attempt at repeating something they've learnt. All of the examples in The
Schools' Collection subsitute &lt;i&gt;i gcúl&lt;/i&gt; for &lt;i&gt;a' dul&lt;/i&gt;, changing the
meaning from "eyes coming out of his head" to "eyes on the back of his head",
which makes a lot less sense to me. The version from point 40 of the LASID: &lt;blockquote&gt;
Brian O Slupáin agus a chois tinn,&lt;br&gt;barr a bhróige i bpoll a thóna,&lt;br&gt;agus a dhá shúil mhóra amuigh ós a chionn
&lt;/blockquote&gt;
The versions I found in The Schools' Collection: &lt;ul&gt; &lt;li&gt;&lt;a href=https://www.duchas.ie/en/cbes/4622967/4618072/4628513&gt;An Trá Bháin,
Contae na Gaillimhe&lt;/a&gt;. This is the fullest version in The Schools'
Collection. The frog is named &lt;i&gt;Seán Ó Lupáin&lt;/i&gt;, "Johnny McHands" perhaps.&lt;/li&gt; &lt;li&gt;
&lt;a href=https://www.duchas.ie/en/cbes/4613689/4608972/4659073&gt;An Spidéal, Contae
na Gaillimhe&lt;/a&gt;. This is very truncated. The frog is named &lt;i&gt;Mach Uí
Stíopháin&lt;/i&gt;. It is a little hard to make out of the "t" in &lt;i&gt;Stíopháin&lt;/i&gt;
is indeed a "t".&lt;/li&gt;&lt;li&gt;
&lt;a href=https://www.duchas.ie/en/cbes/4572372/4565414/4572388&gt;Gaillimh&lt;/a&gt;.
  This one varies the most from the others.&lt;/li&gt;&lt;li&gt;
  &lt;a href=https://www.duchas.ie/en/cbes/4427990/4364623/4468321&gt;An tInbhear,
Contae Mhaigh Eo&lt;/a&gt;. Also very truncated. The frog is called &lt;i&gt;Mach Uí
Stiopháin&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;
&lt;a href=https://www.duchas.ie/en/cbes/5235172/5224715/5243655&gt;Béal Feirste,
Contae Mhaigh Eo&lt;/a&gt;. Also very truncated. The frog is called &lt;i&gt;Mac Ui
Shliop&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;
&lt;a href=https://www.duchas.ie/en/cbes/5235172/5225191/5260368&gt;Béal Feirste,
Contae Mhaigh Eo&lt;/a&gt;. The riddle is (presumably accidentally) repeated twice.
The frog
is called &lt;i&gt;Mac I Shliopán&lt;/i&gt;.&lt;/li&gt;
&lt;/ul&gt; Vaguely similar riddles elsewhere: &lt;ul&gt; &lt;li&gt;&lt;a href=https://www.duchas.ie/en/cbes/4687698/4684993/4689936&gt;Baile Uí
  Dhuinn, Contae Chiarraí&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:riddle" title="Jump back to footnote 25 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:neologisms"&gt;
&lt;p&gt;Dorian (1981) pp. 111-112: &lt;blockquote&gt;There are at least five aspects of
linguistic behaviour [...] in which the dominance of English over Gaelic is
less complete than might be anticipated. First, despite the association of
English with modernity and technology and the public spheres of life, no topic
connected with these aspects of life forces a choice of English. If the setting
and the interlocutor permit, any topic, no matter how sophisticated or remote
from local life, can be discussed in Gaelic. Closely related to this aspect of
resistance to English dominance is the thorough-going integration of English
lexical borrowings into Gaelic; &lt;b&gt;this integration makes possible the use of
Gaelic for all topics&lt;/b&gt;."&lt;/blockquote&gt; Emphasis my own. The idea that an expanded
"native" lexicon is required for a language to expand its spheres of usage is
also rejected in Lewin (2016): &lt;blockquote&gt;"[on a quote declaring Fargher's dictionary as
making it possible for Manx speakers to discuss topics like atomic physics]
This passage implies that it was impossible to discuss subjects like atomic
physics etc. before the appearance of the dictionary, ignoring the fact that
many neologisms had been developed and were in use within the small community
of speakers in earlier decades, not to mention the fact that Manx speakers are
at liberty to borrow from English specific lexis where no pre-existing Manx
word exists or is remembered."&lt;/blockquote&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:neologisms" title="Jump back to footnote 26 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:vandal"&gt;
&lt;p&gt;This replacement of native speakers' grammar, erasing a unique history
of language contact and adaptation, is something I can see only as cultural
vandalism. However, for more nuanced and detailed thoughts
on Fargher's work I will again refer to Lewin's work. As he puts it in Lewin
(2017): &lt;blockquote&gt; [it is perhaps] problematic if the native Manx of the
   past is implicitly (or explicitly) rejected as being not Manx enough.
   Efforts to purge Manx of grammatical and lexical influence from English
   arguably constitute a purism of a simplistic and unnecessarily xenophobic
   kind, which disregards the lived experience of centuries of Manx speakers,
   for whom some contact with English and borrowing of English forms was an
   inherent part of their linguistic world, and reflects a discourse which
   comes close to blaming the traditional speakers for letting their language
   become ‘impure’. It also makes the native Manx texts of the past less
   accessible to new speakers.&lt;/blockquote&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:vandal" title="Jump back to footnote 27 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/></entry><entry><title>"The most common vowel in English"?</title><link href="https://mcla.ug/schwa.html" rel="alternate"/><published>2025-10-20T00:00:00+01:00</published><updated>2025-10-20T00:00:00+01:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2025-10-20:/schwa.html</id><summary type="html">&lt;h2&gt;&lt;span class=ipa&gt;[hʉz̥ ɪ̞̠̃ŋgɫɪ̞̠ʃ]&lt;/span&gt;?&lt;/h2&gt;
&lt;p&gt;Popular factoids about the English language often leave me feeling contrarian,
as a native speaker of a variety of English often not included in these
broad, unqualified statements. "English has no second person plural"? What do
&lt;a href="https://en.wikipedia.org/wiki/Category:Second-person_plural_pronouns_in_English" target="”_blank”"&gt;yous&lt;/a&gt; mean? And the
&lt;a href="https://www.youtube.com/watch?v=qu4zyRqILYM" target="”_blank”"&gt;seemingly&lt;/a&gt; ever
&lt;a href="https://xkcd.com/2907/" target="_blank"&gt;popular&lt;/a&gt;: "schwa is the …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;&lt;span class=ipa&gt;[hʉz̥ ɪ̞̠̃ŋgɫɪ̞̠ʃ]&lt;/span&gt;?&lt;/h2&gt;
&lt;p&gt;Popular factoids about the English language often leave me feeling contrarian,
as a native speaker of a variety of English often not included in these
broad, unqualified statements. "English has no second person plural"? What do
&lt;a href="https://en.wikipedia.org/wiki/Category:Second-person_plural_pronouns_in_English" target="”_blank”"&gt;yous&lt;/a&gt; mean? And the
&lt;a href="https://www.youtube.com/watch?v=qu4zyRqILYM" target="”_blank”"&gt;seemingly&lt;/a&gt; ever
&lt;a href="https://xkcd.com/2907/" target="_blank"&gt;popular&lt;/a&gt;: "schwa is the most common vowel in English".&lt;/p&gt;
&lt;p&gt;This last statement has often left me puzzled, as I've never been able to
confidently perceive this sound in my own speech. Is this a lack of skill, a
misunderstanding, or is my phonemic intuition pointing at some truth about my
English that can make me feel superiorly contrarian once again?&lt;/p&gt;
&lt;h2&gt;My English&lt;/h2&gt;
&lt;p&gt;In the Tom Scott &lt;a href="https://www.youtube.com/watch?v=qu4zyRqILYM" target="”_blank”"&gt;video&lt;/a&gt; linked above (which you should watch if you don't know
what "schwa" is) he says to the viewer "[when you name the
letter "a"] you're actually
making two separate vowel sounds, &lt;span
class=ipa&gt;/eɪ/&lt;/span&gt;". A bold statement, because I say it with a monophthong:
&lt;span class=ipa&gt;/e/&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Compare a Southern Standard British English
&lt;a href="https://www.oed.com/dictionary/face_n?tl=true&amp;amp;tab=pronunciation" target="_blank"&gt;recording&lt;/a&gt; of "face" &lt;span
class=ipa&gt;[fɛjs]&lt;/span&gt;&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;video width=80% controls&gt;
  &lt;source src="/images/analysing-my-own-speech/face-ssbe.mp4" type="video/mp4"&gt;
&lt;/video&gt;

&lt;p&gt;to me saying "face" &lt;span class=ipa&gt;[fes]&lt;/span&gt;:&lt;/p&gt;
&lt;video width=80% controls&gt;
  &lt;source src="/images/analysing-my-own-speech/face.mp4" type="video/mp4"&gt;
&lt;/video&gt;

&lt;p&gt;They sound quite different&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;, and you can see in the spectrogram (which shows
frequency content over time) that the formants (the most prominent frequencies)
of the SSBE vowel vary, but are very steady in mine:&lt;/p&gt;
&lt;p&gt;&lt;img alt="face-formant-comparison" src="/images/analysing-my-own-speech/face-compare-spectrograms.png"&gt;&lt;/p&gt;
&lt;p&gt;So where do you think I'm from? If you know much about accents of English then
there are only a few options based on my pronunciation of "face" and my being a
native speaker, and I don't think my being disgruntled by an English person
incorrectly telling me how I speak does much to narrow it down. Here's a bit
more of my speech, taken from my reading of &lt;a href="https://www.dialectsarchive.com/comma-gets-a-cure" target="”_blank”"&gt;"Comma Gets a
Cure"&lt;/a&gt;, before I tell you
more:&lt;/p&gt;
&lt;p&gt;"that itchy goose" &lt;span class=ipa&gt;[ðaʔ ɪ̞̠t͡ʃe gʉs]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/itchy-goose.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;&lt;/p&gt;
&lt;p&gt;And here's a clip from a voice note sent to some pals, for a sample of some
more spontaneous speech:
&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/voicenote.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;&lt;/p&gt;
&lt;p&gt;That's right, I'm Scottish! But despite this being a post about my speech, I'm
not going to share too many more clips, because I am shy, and because I don't
want you to make a clone of my voice.&lt;/p&gt;
&lt;p&gt;Here are some known and possible influences on my
speech:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I grew up in Edinburgh in the east of Scotland.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I was raised by my parents who are both from Clydebank in the west of
  Scotland.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I went to university in Cambridge in England 2010-2014, living there about
  half the year.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I lived in Cambridge full-time 2014-2019.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I have lived in Oxford since 2019.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;My partner is English, from Surrey.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;My maternal grandmother was from Donegal in Ireland, as were my maternal
  grandfather's parents. I spent most summers in Donegal as a child.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I was born in the early 1990s.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any city has a wide range of speech, and I wouldn't say my speech is
representative, but I would say it's not atypical of where I'm from&lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;. I
think living in England has undoubtedly changed my accent, which makes me sad,
but it's still distinctively Scottish. I think any Irish influence is not
phonetic, but shows up in some turns of phrase and syntax, like use of
Hiberno-English "would"&lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;4&lt;/a&gt;&lt;/sup&gt; and "so"&lt;sup id="fnref:5"&gt;&lt;a class="footnote-ref" href="#fn:5"&gt;5&lt;/a&gt;&lt;/sup&gt;. This is the main influence on
my mother's speech also, though she also makes pulmonic ingressive sounds
like the inhaled "yeah"s
&lt;a href="https://www.youtube.com/watch?v=71Ziqdt52Eo" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Common transcriptions of schwa &lt;span class=ipa&gt;/ə/&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;There are a few places where SSBE and many American accents&lt;sup id="fnref:6"&gt;&lt;a class="footnote-ref" href="#fn:6"&gt;6&lt;/a&gt;&lt;/sup&gt; have schwa.
Making reference to Wells' &lt;a href="https://en.wikipedia.org/wiki/Lexical_set" target="_blank"&gt;lexical
sets&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;COMMA: words that end with an open syllable (i.e. with a vowel) are
  transcribed as ending in schwa in both
  &lt;a href="http://seas3.elte.hu/cube/index.pl?s=comma" target="_blank"&gt;SSBE&lt;/a&gt; and in
  &lt;a href="https://www.merriam-webster.com/dictionary/comma" target="_blank"&gt;General American&lt;/a&gt;, e.g.
  &lt;span class=ipa&gt;/kɔmə/&lt;/span&gt; (SSBE) and &lt;span class=ipa&gt;/kɑmə/&lt;/span&gt; (Am)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;NURSE: stressed syllables with Middle English &lt;span class=ipa&gt;/i/, /ɛ/,
  /u/&lt;/span&gt; followed by &lt;span class=ipa&gt;/r/&lt;/span&gt;. E.g. &lt;span
  class=ipa&gt;/nəːs/&lt;/span&gt; (SSBE) and &lt;span class=ipa&gt;/nərs/&lt;/span&gt; (Am).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In &lt;a href="https://www.youtube.com/watch?v=EaXYas58_kc" target="_blank"&gt;weak&lt;/a&gt; (unstressed) forms of
  certain common single syllable words like "the", "a", "at".&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In many unstressed syllables, for example in these SSBE
  transcriptions&lt;sup id="fnref:7"&gt;&lt;a class="footnote-ref" href="#fn:7"&gt;7&lt;/a&gt;&lt;/sup&gt;: "villain" &lt;span class=ipa&gt;/vɪlən/&lt;/span&gt;; "patent" &lt;span
  class=ipa&gt;/patənt/&lt;/span&gt;; "synthesis" &lt;span class=ipa&gt;/sɪnθəsɪs/&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some accents of English (including many Americans, and perhaps
  increasingly speakers whose speech could be described as SSBE) use schwa in
  even more unstressed syllables where older southern English accents would
  have &lt;span class=ipa&gt;/ɪ/&lt;/span&gt;, for example "private" as &lt;span
  class=ipa&gt;/praɪvət/&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some accents of English (including many
  &lt;a href="https://www.youtube.com/watch?v=wt66Je3o0Qg" target="_blank"&gt;Americans&lt;/a&gt;, but also some
  northwest English and Welsh accents) use schwa for the STRUT lexical set
  (e.g. "gun", "love", "much" "blood").&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So what about my English? Intuitively I can say:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;My COMMA vowel is far too open to be schwa&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Like all Scottish people I know, the NURSE vowels didn't all
  &lt;a href="https://en.wikipedia.org/wiki/English-language_vowel_changes_before_historic_/r/#Nurse_mergers" target="_blank"&gt;merge&lt;/a&gt;
  for me. I think everyone I know (biased to the central belt&lt;sup id="fnref:8"&gt;&lt;a class="footnote-ref" href="#fn:8"&gt;8&lt;/a&gt;&lt;/sup&gt;) has &lt;span
  class=ipa&gt;/fʌr/&lt;/span&gt;&lt;sup id="fnref:9"&gt;&lt;a class="footnote-ref" href="#fn:9"&gt;9&lt;/a&gt;&lt;/sup&gt; for "fir" and "fur". I say &lt;span
  class=ipa&gt;/fɛrn/&lt;/span&gt; for "fern", often realised &lt;span
  class=ipa&gt;[fɛɾɪ̆n]&lt;/span&gt;. Similarly I say "world" as &lt;span
  class=ipa&gt;[wʌɾʌ̆ɫd]&lt;/span&gt;&lt;sup id="fnref:10"&gt;&lt;a class="footnote-ref" href="#fn:10"&gt;10&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I'm less sure about the remaining examples, but some of them I would
  identify with my KIT vowel rather than schwa.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I did some crude formant analysis&lt;sup id="fnref:11"&gt;&lt;a class="footnote-ref" href="#fn:11"&gt;11&lt;/a&gt;&lt;/sup&gt; comparing my vowels in the KIT, STRUT, and
COMMA lexical sets, and weak forms of non-content words.&lt;/p&gt;
&lt;p&gt;&lt;img alt="kit-strut-comma" src="/images/analysing-my-own-speech/kit-strut-comma.svg"&gt;
&lt;img alt="weak-forms" src="/images/analysing-my-own-speech/weak-forms.svg"&gt;&lt;/p&gt;
&lt;p&gt;What I'm taking from this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My commA vowel is equivalent to my STRUT vowel&lt;/li&gt;
&lt;li&gt;My KIT vowel is used in weak forms of non-content words&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What about unstressed syllables in words like "villain" and "synthesis"? The
&lt;a href="https://www.dialectsarchive.com/comma-gets-a-cure" target="_blank"&gt;passage&lt;/a&gt;I used for most of
my analysis had very few incidences of these syllables&lt;sup id="fnref:12"&gt;&lt;a class="footnote-ref" href="#fn:12"&gt;12&lt;/a&gt;&lt;/sup&gt;, so I recorded
myself saying individual words&lt;sup id="fnref:13"&gt;&lt;a class="footnote-ref" href="#fn:13"&gt;13&lt;/a&gt;&lt;/sup&gt;. There they are for your enjoyment and
analysis:&lt;/p&gt;
&lt;p&gt;&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/schwa.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;&lt;/p&gt;
&lt;p&gt;These words, along with "woman" (from my passage reading), are plotted here
against my KIT and STRUT vowels:&lt;/p&gt;
&lt;p&gt;&lt;img alt="kit-strut-schwa" src="/images/analysing-my-own-speech/schwa.svg"&gt;&lt;/p&gt;
&lt;p&gt;At last! A distinct schwa vowel. So it does exist! The outlier among the KIT
vowels is "woman" which I pronounce with &lt;span class=ipa&gt;/ɪ/&lt;/span&gt;. In fact,
many of the KIT examples I used were unstressed and would have been schwa in an
accent with a complete &lt;a href="https://en.wikipedia.org/wiki/Phonological_history_of_English_close_front_vowels#Weak_vowel_merger" target="_blank"&gt;weak vowel
merger&lt;/a&gt;.
&lt;small&gt;&lt;small&gt;But I'm not going to redo the analysis, I feel like it doesn't
materially affect it.&lt;/small&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;With weak forms:&lt;/p&gt;
&lt;p&gt;&lt;img alt="kit-strut-schwa-weak" src="/images/analysing-my-own-speech/schwa-vs-weak.svg"&gt;&lt;/p&gt;
&lt;p&gt;And with COMMA:&lt;/p&gt;
&lt;p&gt;&lt;img alt="kit-strut-comma-schwa" src="/images/analysing-my-own-speech/kit-strut-comma-schwa.svg"&gt;&lt;/p&gt;
&lt;p&gt;So in summary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;My STRUT vowel is distinct from schwa&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;My COMMA vowel is equivalent to my STRUT vowel, though perhaps sometimes goes
  more central towards schwa&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;My KIT vowel is used in weak forms of non-content words&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I have an incomplete weak vowel merger, where some unstressed syllables that
  might be pronounced &lt;span class=ipa&gt;/ɪ/&lt;/span&gt; are instead &lt;span class=ipa&gt;/ə/&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, is schwa the most common vowel in my English? It certainly doesn't seem
like it.  In my reading of &lt;a href="https://www.dialectsarchive.com/comma-gets-a-cure" target="_blank"&gt;"Comma Gets a
Cure"&lt;/a&gt;, I think the only
word I use a schwa in is in the second syllable of "millionaire". (See this
footnote&lt;sup id="fnref2:12"&gt;&lt;a class="footnote-ref" href="#fn:12"&gt;12&lt;/a&gt;&lt;/sup&gt;.) One incidence in the entire passage doesn't sound like much to
me! I think my having schwa only in some places in one of the many categories
of syllables where schwa is usually pronounced results in this relatively rare
incidence. Perhaps &lt;span class=ipa&gt;/ɪ/&lt;/span&gt; is my most common vowel, on
account of my using it for weak forms.&lt;/p&gt;
&lt;p&gt;Superior contrarian feeling achieved 😌.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Appendix A: How mid-central is the vowel I've labelled "schwa"?&lt;/h2&gt;
&lt;p&gt;Something I haven't pointed out elsewhere in this post is that phonetic symbols
and names like "schwa" have somewhat ambiguous and highly contextual meanings.&lt;/p&gt;
&lt;p&gt;Take my KIT vowel, for example. I've seen &lt;a href="https://en.wikipedia.org/wiki/Scottish_English#/media/File:Scottish_English_monophthongs_chart.svg" target="_blank"&gt;vowel
diagrams&lt;/a&gt;
for Scottish English that put the KIT vowel much closer to schwa than the IPA
chart shows &lt;span class=ipa&gt;[ɪ]&lt;/span&gt;. Similarly
&lt;a href="https://en.wikipedia.org/wiki/Received_Pronunciation#/media/File:Modern_General_British_monophthong_chart.svg" target="”_blank”"&gt;this&lt;/a&gt;
"modern RP" vowel chart has a slightly lowered vowel.&lt;/p&gt;
&lt;p&gt;Here they are superimposed, with the IPA's reference vowels shown in pink:&lt;/p&gt;
&lt;p&gt;&lt;img alt="I-vowel-comparison" src="/images/analysing-my-own-speech/I-vowel-comparison.svg"&gt;&lt;/p&gt;
&lt;p&gt;I'm not sure if this is an accurate plot of where my KIT vowel is, but it seems
plausible.&lt;/p&gt;
&lt;p&gt;There's an implicit assumption in my blog post that this difference between the
IPA's definition of &lt;span class=ipa&gt;[ɪ]&lt;/span&gt; and my realisation of &lt;span
class=ipa&gt;/ɪ/&lt;/span&gt; is irrelevant to our discussions.&lt;/p&gt;
&lt;p&gt;In a similar vein, when people repeat the meme of "schwa is the most common
vowel in English", it can be unclear exactly what vowel they mean, and whether
they are even aware of what they mean&lt;sup id="fnref:14"&gt;&lt;a class="footnote-ref" href="#fn:14"&gt;14&lt;/a&gt;&lt;/sup&gt;. Do they mean any unstressed reduced
vowel in their English? Specifically something in the near vicinity of the
mid-central vowel on the IPA chart? Or just any sound they've seen transcribed
as &lt;span class=ipa&gt;/ə/&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;Anyway, here is me attempting a perfectly mid-central unrounded vowel, followed by my
KIT vowel:&lt;/p&gt;
&lt;video width=80% controls&gt;
  &lt;source src="/images/analysing-my-own-speech/schwa-vs-I.mp4" type="video/mp4"&gt;
&lt;/video&gt;

&lt;p&gt;Formant analysis shows &lt;span class=ipa&gt;/ɪ/&lt;/span&gt; with a slightly higher F1 and
a more noticeably higher F2. This would make sense, as it would suggest a
slightly less open, and noticeably more fronted vowel.&lt;/p&gt;
&lt;p&gt;But how do the formants for my "perfect" mid-central vowel compare to the ones
analysed in my speech?&lt;/p&gt;
&lt;p&gt;&lt;img alt="perfect" src="/images/analysing-my-own-speech/perfect.svg"&gt;&lt;/p&gt;
&lt;p&gt;Lol! It's hard to know if this is because my attempt at a phonetically perfect
mid-central vowel was poor, or because the vowels I labelled schwa live
somewhere else on the vowel chart. Regardless, using &lt;span class=ipa&gt;/ə/&lt;/span&gt;
to transcribe them is in keeping with tradition, particularly as they seem to
contrast with my KIT vowel (which if it was my only mid-central vowel, you
could argue would be sensibly transcribed as &lt;span class=ipa&gt;/ə/&lt;/span&gt;).&lt;/p&gt;
&lt;h2&gt;Appendix B: But what about, eeh, what's it called, "the hesitation vowel"?&lt;/h2&gt;
&lt;p&gt;Schwa is also sometimes called "the hesitation vowel", the vowel that English
speakers use when they're trying to figure out what to say next. But I think I generally use my DRESS (or maybe FACE?) vowel if I'm
going to make a vocalic hesitation noise while speaking, or maybe STRUT. Here
are some examples taken from voice notes I sent friends:&lt;/p&gt;
&lt;p&gt;&lt;span class=ipa&gt;/ɛ/&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/hesitation-3.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;
&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/hesitation-1.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;
&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/hesitation-0.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=ipa&gt;/ɛm/&lt;/span&gt;? &lt;span class=ipa&gt;/ɛrm/&lt;/span&gt;?&lt;/p&gt;
&lt;p&gt;&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/hesitation-2.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;&lt;/p&gt;
&lt;p&gt;I think there's an idea that because the tongue position for schwa is
"neutral", i.e. the tongue is at the mid-point of both the open-closed and
front-back axes, that it's natural for speakers to default to it when
reaching for what to say next.&lt;/p&gt;
&lt;p&gt;I think what's natural is of course dependent on your native language(s). Take
a look at these vowel diagrams for
&lt;a href="https://en.wikipedia.org/wiki/Standard_Arabic_phonology#/media/File:Arabic_vowels_(Monophthongs).png" target="_blank"&gt;Arabic&lt;/a&gt;
(three vowels),
&lt;a href="https://en.wikipedia.org/wiki/Japanese_phonology#/media/File:Japanese_vowel_chart_II.svg" target="_blank"&gt;Japanese&lt;/a&gt; (five vowels), and
&lt;a href="https://en.wikipedia.org/wiki/Italian_phonology#/media/File:Italian_vowel_chart.svg" target="_blank"&gt;Italian&lt;/a&gt;
(seven vowels)&lt;sup id="fnref:15"&gt;&lt;a class="footnote-ref" href="#fn:15"&gt;15&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;None of these show a schwa vowel. In Japanese it's most common to hear
ええっと&lt;span class=ipa&gt;[e̞ːt̚to̞]&lt;/span&gt;&lt;sup id="fnref:16"&gt;&lt;a class="footnote-ref" href="#fn:16"&gt;16&lt;/a&gt;&lt;/sup&gt;. The two vowels used there are both
central, though they are front and back, respectively. My hesitation vowel is
also mid. Is there something cross-linguistic at play here?&lt;/p&gt;
&lt;p&gt;A brief look at this &lt;a href="https://www.reddit.com/r/languagelearning/comments/mbvn63/are_hesitation_noises_different_in_various/" target="_blank"&gt;Reddit
thread&lt;/a&gt;
suggests some variation, but a lot of languages are listed as having mid vowel
sounds, if I'm interpreting the crude transcription correctly: German, Kyrgyz,
Finnish, Spanish. Notable exceptions appear to be Mandarin, Korean and
Polish. This is quite a crude source of information however.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;i&gt;
I love learning about phonetics and phonology: I love learning how speech
sounds are made, about differences and similarities between the sounds of
different languages, and how some differences in speech are immediately
perceptible depending on context and your native language, and others are much
harder to perceive.&lt;/p&gt;
&lt;p&gt;I haven't posted on my blog in a while, and none of my previous posts have
reflected this interest. I have a few fun ideas for projects and blog posts
around these topics. Some of them are cross-language, some are specific to the
second languages I am learning: Irish Gaelic and Japanese.&lt;/p&gt;
&lt;p&gt;This post was my first try at posting about phonetics. If this is something you have expertise in, and you have any
thoughts on my analysis, please do e-mail me at &lt;a href="mailto:h@mcla.ug"&gt;h@mcla.ug&lt;/a&gt;! I am not an expert and am very keen to
learn.
&lt;/i&gt;&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;If you're interested in why I've used a different transcription to Tom
Scott for the SSBE pronunciation of "face", I recommend this
&lt;a href="https://www.youtube.com/watch?v=gtnlGH055TA"&gt;video&lt;/a&gt; from Geoff Lindsey&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Mine is also shorter mostly because it is clipped from a longer
utterance, whereas the SSBE recording is from a dictionary where the speaker
has uttered a single word.&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Apart from my pronuncation of words like "stair" with &lt;span
class=ipa&gt;/ɛ/&lt;/span&gt; instead of &lt;span class=ipa&gt;/e/&lt;/span&gt;. Compare my
pronunciation of Sarah Perry &lt;span class=ipa&gt;[sɛɾʌ pʰɛɾe]&lt;/span&gt;:&lt;/br&gt;
&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/sarah-perry.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;
&lt;/br&gt;
to my school pal's &lt;span class=ipa&gt;[seɾʌ pʰɛɾe]&lt;/span&gt;.
&lt;/br&gt;
&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/rosie-sarah-perry.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;
&lt;/br&gt;
My mother's is similar to mine:
&lt;/br&gt;
&lt;audio controls&gt;
  &lt;source src="/images/analysing-my-own-speech/mum-sarah-perry.wav" type="audio/wav"&gt;
Your browser does not support the audio element.
&lt;/audio&gt;&lt;/br&gt;
In Wells' "Accents of English" he says: "There are some Scots who have &lt;span
class=ipa&gt;/ɛr/&lt;/span&gt; rather than &lt;span class=ipa&gt;/er/&lt;/span&gt; in SQUARE: they
will say &lt;i&gt;upst[ɛː]rs&lt;/i&gt;, not &lt;i&gt;upst[eː]rs&lt;/i&gt;. I have heard the claim that
this pronuncation is used only by Roman Catholics in the Glasgow conurbation,
and that it is due to Irish influence. I am not in a position to
substantiate or disconfirm this claim." My mother is indeed from Glasgow and we
are indeed Fenians.&amp;#160;&lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;Example: "I'd be a fan of that now" instead of "I am a fan". Or "she
wouldn't be rich" instead of "she isn't rich". This feels natural to me, and I
think I use it to indicate a certain subjectiveness or personal perspective. I
do come across more objective usages that are less natural to me. Recently my
cousin asked me "would you wear make-up". For the same meaning I would have
said "do you wear make-up". So I wouldn't say I use it as broadly as people in
Ireland.&amp;#160;&lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;Example: "I'll go do that then so", not really sure what meaning the
"so" adds but I think I say this all the time. Looking this up, it seems it's
common in Ireland to replace "then" with "so" in such phrases, so perhaps I'm
doubling up! But this is what I say. I also say "ok so" but don't think I
really say "ok then".&amp;#160;&lt;a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 5 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;I don't know enough about American English accents to go into much detail
about cultural and geographical factors that might affect the usage of schwa,
despite being constantly subjected to American voices by media that I
choose to consume of my own volition. I'm sorry if you are American and what I
write here does not represent your accent. I have tried to make it clear that I
am talking about &lt;em&gt;some&lt;/em&gt; American accents and talking in broad terms of what
dictionaries often transcribe things as.&amp;#160;&lt;a class="footnote-backref" href="#fnref:6" title="Jump back to footnote 6 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:7"&gt;
&lt;p&gt;Taken from the &lt;a href="http://seas3.elte.hu/cube"&gt;CUBE dictionary&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:7" title="Jump back to footnote 7 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:8"&gt;
&lt;p&gt;I have read speakers from other areas have &lt;span class=ipa&gt;/fɪr/&lt;/span&gt;
for "fir". It's not like I've never met or heard anyone from outside the
central belt! But not since I gained the sort of phonetic awareness that might
cause me to notice this difference in pronunciation.&amp;#160;&lt;a class="footnote-backref" href="#fnref:8" title="Jump back to footnote 8 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:9"&gt;
&lt;p&gt;My STRUT vowel has definitely changed a bit from living in England. When
I am chatting to my Scottish pals or speaking loudly (e.g. over a noisy pub),
my vowel changes to (I think) further back and more open.&amp;#160;&lt;a class="footnote-backref" href="#fnref:9" title="Jump back to footnote 9 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:10"&gt;
&lt;p&gt;I haven't included any formant analysis for this set. It's harder to
segment the vowels next to approximants, and I think some of my realisations
are r-coloured vowels, which skews the F3 formant in a way that I think is
distracting.&amp;#160;&lt;a class="footnote-backref" href="#fnref:10" title="Jump back to footnote 10 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:11"&gt;
&lt;p&gt;I manually segmented the vowels and used the default formant analysis in
Praat's vocal toolkit. I visually inspected the spectrograms to ensure the
formants looked sensible. Most of the tokens are from my reading of
&lt;a href="https://www.dialectsarchive.com/comma-gets-a-cure"&gt;"Comma Gets a Cure"&lt;/a&gt;. I
conceived the vowel distance plots myself from my understanding that relative
difference between formants was most important for perception, so if you're a
linguist and have thoughts on their usefulness I'd be grateful. I think they
match what is done in the Bark Difference metric described
&lt;a href="https://lingtools.uoregon.edu/norm/norm1_methods.php"&gt;here&lt;/a&gt;, without
cross-speaker normalisation (as it's just me speaking).&amp;#160;&lt;a class="footnote-backref" href="#fnref:11" title="Jump back to footnote 11 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:12"&gt;
&lt;p&gt;The words I picked out were: "woman" (two incidences, one of which had
indistinct formants), "millionaire" (indistinct formants, perhaps due
to pharyngealised /l/), "beautiful" (I have no intervening vowel between /f/
and /l/), "suffering" (I have no intervening vowel between /f/ and /r/). So
only one usable token. In retrospect words like "private" could also have been
used here, but as the CUBE dictionary transcribes it &lt;span
class=ipa&gt;prɑjvɪt&lt;/span&gt; I had some impression that there was a difference
between this and the other words. But I think it's just reflecting an
incomplete weak vowel merger. I also use &lt;span class=ipa&gt;/ɪ/&lt;/span&gt; in
"private".&amp;#160;&lt;a class="footnote-backref" href="#fnref:12" title="Jump back to footnote 12 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;a class="footnote-backref" href="#fnref2:12" title="Jump back to footnote 12 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:13"&gt;
&lt;p&gt;This is less desirable as there's always a chance I might
self-consciously pronounce the words differently than normal, or just stating
them in isolation might be different from saying them in connected speech. But
I think the recording sounds very normal to me.&amp;#160;&lt;a class="footnote-backref" href="#fnref:13" title="Jump back to footnote 13 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:14"&gt;
&lt;p&gt;There are many linguists I respect, like Geoff Lindsey, who have said
schwa is the most common vowel in English. I am not questioning whether he
knows what he's talking about, more pointing out how much of a meme the "fact"
has become, hence it is repeated without necessarily being understood.&amp;#160;&lt;a class="footnote-backref" href="#fnref:14" title="Jump back to footnote 14 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:15"&gt;
&lt;p&gt;All of these languages have "non-standard" varieties, where I'm sure the
vowels vary significantly. Certainly there are varieties of Japanese with
&lt;a href="https://en.wikipedia.org/wiki/Nagoya_dialect"&gt;more&lt;/a&gt; or
 &lt;a href="https://en.wikipedia.org/wiki/Northern_Izu_Archipelago_dialects"&gt;less&lt;/a&gt;
vowels than shown here. My knowledge of Arabic and Italian is much less.&amp;#160;&lt;a class="footnote-backref" href="#fnref:15" title="Jump back to footnote 15 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:16"&gt;
&lt;p&gt;Japanese has a lot of "filler"
&lt;a href="https://en.wikipedia.org/wiki/Aizuchi"&gt;words&lt;/a&gt; that are quite
important parts of holding a conversation. I feel like ええっと or ええと or
えっと is the best analogy for the places I would usually hestitate and go
"eee" or "eem". One of the Reddit comments on the linked thread is about
Japanese and lists some of these but I feel like only あの and ええと are used
for unconscious hesitation, and the others are more expressive of specific
sentiments. I would use あの more if I was shyly interrupting or about to say
something I felt shy about, and えっと for stalling while I think of the next
word to say. I am not a native speaker, however.&amp;#160;&lt;a class="footnote-backref" href="#fnref:16" title="Jump back to footnote 16 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/></entry><entry><title>Intro to Quantum Computing</title><link href="https://mcla.ug/qc-intro.html" rel="alternate"/><published>2024-07-27T00:00:00+01:00</published><updated>2024-07-27T00:00:00+01:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2024-07-27:/qc-intro.html</id><summary type="html">&lt;script&gt;
window.MathJax = {
  loader: {load: ['[tex]/braket']},
  tex: {packages: {'[+]': ['braket']}}
};

MathJax = {
  tex: { inlineMath: [['$', '$']] }
};
&lt;/script&gt;

&lt;script id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3.0.0/es5/tex-mml-chtml.js"&gt;
&lt;/script&gt;

&lt;p&gt;I work at a trapped ion quantum computing company writing compiler and control
software in Rust and Python. I've had to learn about quantum computing for my
work, and I have found it hard to find introductory literature …&lt;/p&gt;</summary><content type="html">&lt;script&gt;
window.MathJax = {
  loader: {load: ['[tex]/braket']},
  tex: {packages: {'[+]': ['braket']}}
};

MathJax = {
  tex: { inlineMath: [['$', '$']] }
};
&lt;/script&gt;

&lt;script id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3.0.0/es5/tex-mml-chtml.js"&gt;
&lt;/script&gt;

&lt;p&gt;I work at a trapped ion quantum computing company writing compiler and control
software in Rust and Python. I've had to learn about quantum computing for my
work, and I have found it hard to find introductory literature that is both
informative and accessible to me.&lt;/p&gt;
&lt;p&gt;I thought it would be nice to put together my own introductory guide, and in
the process improve my own understanding. After a lot of reading, and a lot of
questions answered by my excellent colleague Dr Amy Hughes, I've put something
together that covers some of what I was hoping.&lt;/p&gt;
&lt;p&gt;I think the first section should be accessible even without much maths or
physics knowledge. After that, some basic linear algebra knowledge will be
helpful, as well as some basic knowledge of atomic structure.&lt;/p&gt;
&lt;p&gt;I hope this will elucidate the basic idea of how quantum algorithms work, what
"superposition" and "entanglement" mean and why they are useful, and give a
concrete physical illustration of how these abstract ideas can be realised on
an actual qubit.&lt;/p&gt;
&lt;h2&gt;Unpacking the hype&lt;/h2&gt;
&lt;p&gt;There are two properties of quantum computers that you might have heard about,
expressed variously:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Qubits can be in many states at once! Each qubit exists in a &lt;em&gt;superposition&lt;/em&gt;
of 0 and 1!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We can &lt;em&gt;entangle&lt;/em&gt; qubits together, so that the state of one qubit determines
the state of others!&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Somehow we are to believe that these properties allow quantum computers to be
large and efficient parallel machines. In some sense this is true:
superposition allows quantum computers to explore multiple computational paths
simultaneously, and entanglement creates a state space that grows exponentially
with the number of qubits. But when you measure a qubit, you get a value of $0$
or $1$. So what good are our vast parallelised computations if our output is
compact, encoded in the same binary digits we get out of a classical
computation?&lt;/p&gt;
&lt;figure&gt;
    &lt;p align="center"&gt;
    &lt;img src="images/qc-intro/profit.svg" id="profit" style="width: 100%"
    alt="A block diagram showing a small amount of classical information, in
    the form of arrows, entering a block that says 'something to do with
    superposition and entanglement...maybe?'. Many more arrows exit the box,
    showing the large amount of quantum information. The next block says
    'computation...somehow?', and has a small number of arrows exiting it."&gt;
    &lt;figcaption&gt;&lt;p align="center"&gt;&lt;i&gt;A small amount of classical information becomes a large amount of quantum
information during the quantum computation. But the result is again a small
amount of classic information. How can this be useful?&lt;/i&gt;&lt;/p&gt;&lt;/figcaption&gt;
    &lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;One of the things quantum computers are useful for is extracting some
&lt;em&gt;property&lt;/em&gt; of the large superposed state. So rather than quantum computers
being useful for calculating lots of numbers in parallel, they can be useful
for calculating, say, one number that describes some structure in a vast
collection of many other numbers.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Shor's algorithm&lt;/em&gt;  uses quantum computers in this way. Public-key cryptography
methods such as RSA multiply two large prime numbers together to generate the
encryption key. Those two large prime numbers are kept secret, as the
decryption key can be derived from them. Hence, the security of such encryption
methods relies on it being infeasible for classical computers to find prime
factors of a large integer. In Shor's algorithm, the problem of factoring that
integer is reduced to finding the period of a repeating sequence.  That
sequence is then encoded into the qubits' state and the period is computed as
the compact output of the computation.&lt;/p&gt;
&lt;p&gt;Factoring an $n$-bit integer with Shor's algorithm requires something like
$2n + 3$ logical&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; qubits&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;, depending on the implementation. So for an
2048-bit integer, as often used for RSA keys, something like 5099 logical
qubits would be required. At writing, the most powerful quantum computer in the
world has the equivalent of 20&lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3&gt;Re-visualising the flow of information&lt;/h3&gt;
&lt;p&gt;We can now update &lt;a href="#profit"&gt;our image&lt;/a&gt; above:&lt;/p&gt;
&lt;figure&gt;
    &lt;p align="center"&gt;
    &lt;img src="images/qc-intro/profit-1.svg" id="extract-structure"
    style="width: 100%" alt="Another block diagram with a small number of
    arrows entering the first block. The first block now reads 'expand state
    space', and again has many more arrows exiting it. The next block is
    labelled 'encode input information', and has the same number of arrows
    exiting it. The final box reads 'extract global property of state', and has
    a small number of arrows exiting it, showing the small amount of classical
    information as the output."&gt;
    &lt;figcaption&gt;&lt;p align="center"&gt;&lt;i&gt;Many quantum algorithms exploit the large quantum state space to encode
information that has some kind of large pattern or structure. That structure is
then efficiently extracted.&lt;/i&gt;&lt;/p&gt;&lt;/figcaption&gt;
    &lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;Importantly, quantum computers are not equivalent to many parallel classical
computers. The quantum state space may be vast, but the result of our
computation is compact. This makes them suitable for computations that can be
formulated into the general structure shown in &lt;a href="#extract-structure"&gt;the image above&lt;/a&gt;,
but not for simply parallelising many classical computations.&lt;/p&gt;
&lt;h3&gt;How exactly do we go from lots of quantum information to a small amount of classical information?&lt;/h3&gt;
&lt;p&gt;As we've previously stated, when you measure a qubit you get a compact
result of 0 or 1. Before that measurement, we have a great deal more
information. Don't we want that information? How do we distill the information
we're interested in into our compact output?&lt;/p&gt;
&lt;p&gt;As we'll explore further in a later section, a qubit's state is expressed using
complex numbers that represent measurement probabilities. A qubit in
superposition is one that has &amp;lt;100% probability of being measured as 0 or 1. If
our algorithm resulted in every qubit having a 50% probability of being
measured as 0 or 1, it would be indistinguishable from noise. So probabilistic
quantum algorithms must manipulate the probabilities such that we have a high
probability of measuring something useful.&lt;/p&gt;
&lt;p&gt;Manipulation of qubit state is done via &lt;em&gt;quantum logic gates&lt;/em&gt;, or simply
&lt;em&gt;gates&lt;/em&gt;. All gates are linear operators: each output is some linear combination
of every input. So when we perform a multi-qubit gate, each qubit's state
becomes a weighted sum of the input qubit states. When doing this sum, the
qubit states can cancel each other out (destructive interference) or amplify
each other (constructive interference).&lt;/p&gt;
&lt;p&gt;We can think of our quantum algorithms as exploring many computational
paths, then pruning off those that aren't of interest, leaving us with a high
probability of measuring the result we desire.&lt;/p&gt;
&lt;h2&gt;What does the quantum state actually look like?&lt;/h2&gt;
&lt;h3&gt;For a single qubit&lt;/h3&gt;
&lt;p&gt;The state of a single qubit can be described by two complex numbers, which
encode the probability of measuring $0$ or $1$. If you can forgive the
introduction of some notation without it being fully explained, we'll use
$\ket{0}$ to describe 100% probability of measuring $0$, and $\ket{1}$ for
$1$'s equivalent. Our qubit state $\ket{\psi}$ is then described by a linear
combination of these:&lt;/p&gt;
&lt;p&gt;$$
\ket{\psi} = a_0\ket{0} + a_1\ket{1}, a_i \in \mathbb{C}
$$&lt;/p&gt;
&lt;p&gt;The complex numbers $a_i$ are known as &lt;em&gt;probability amplitudes&lt;/em&gt;, and
their square magnitude gives the probability of measuring the corresponding
output. For example, the probability of measuring $0$ is given by
${\left|a_0\right|}^2$.&lt;/p&gt;
&lt;p&gt;We cannot directly observe the probability amplitudes, only the binary result
of measurement. Why? Intuitively: how could you measure a probability directly?
More honestly: well, why does an electron have charge? There are many things in
the world that we can observe (whether directly or through complex
        experimentation) and describe with mathematics -- but ultimately they
are "just the way it is".&lt;/p&gt;
&lt;h3&gt;For multiple qubits&lt;/h3&gt;
&lt;p&gt;For every $n$ qubits, we have $2^n$ possible measurement outcomes. For example,
for 3 qubits we have possible results of $000, 001, 010, 011, 100, 101,
110, 111$.  Each of these outcomes has a probability amplitude associated
with it:&lt;/p&gt;
&lt;p&gt;$$
\ket{\psi} = a_0\ket{000} + a_1\ket{001} + a_2\ket{010} + \dots a_7\ket{111}
$$&lt;/p&gt;
&lt;p&gt;Why is it necessary to describe the joint probability distribution across all
qubits? Why can't we factor these into independent distributions for each
qubit, giving us $2n$ probability amplitudes instead of $2^n$?&lt;/p&gt;
&lt;p&gt;When qubits are entangled, their measurement outcomes are linked. Therefore,
a general description of the state for multiple qubits must describe a joint
probability distribution over the qubit measurement outcomes, rather than
independent distributions for each qubit.&lt;/p&gt;
&lt;p&gt;Hence, entanglement is what creates the exponential growth of the state space
with the number of qubits.&lt;/p&gt;
&lt;h3&gt;How exactly does the state scale compared to classical computers?&lt;/h3&gt;
&lt;p&gt;It's not obvious how best to quantify the difference in scale between our
$\mathbb{C}^{2^n}$ quantum state space and our $\mathbb{Z}_{2}^{n}$ classical
state space . One way we can directly compare them is by considering degrees of
freedom.&lt;/p&gt;
&lt;p&gt;In a classic computer, we have as many degrees of freedom as we have bits. You
can fully describe the state of $n$ bits with $n$ values of 0 or 1.&lt;/p&gt;
&lt;p&gt;In a quantum computer, the degrees of freedom scale exponentially with the
number of qubits. How?&lt;/p&gt;
&lt;figure&gt;
    &lt;p align="center"&gt;
    &lt;img src="images/qc-intro/scale.svg" style="width: 100%" alt="A graph
    comparing degrees of freedom on y axis, and number of bits on x axis.
    Classical computers have y=x plotted, and quantum computers have y=2^(n+1)
    - 2 plotted"&gt;
    &lt;figcaption&gt;&lt;p align="center"&gt;&lt;i&gt;Comparing how the degrees of freedom in classical and
    quantum computers scale with the number of bits&lt;/i&gt;&lt;/p&gt;&lt;/figcaption&gt;
    &lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;From &lt;a href="#for-multiple-qubits"&gt;our equation for multi-qubit state&lt;/a&gt;, we know that
the state of $n$ qubits is described by $2^n$ complex numbers. Absent any
constraints, $2^n$ complex numbers would have $2 \times 2^n = 2^{n+ 1}$ degrees
of freedom: each complex number is minimally and fully defined by two real
numbers, an amplitude and a phase. As the square magnitudes of our complex
numbers represent probabilities, we have the constraint
$\sum_{i = 0}^{i = 2^n - 1}\left|a_i\right|^2 = 1$, which removes one degree of
freedom. We eliminate another degree of freedom due to the fact that the
relative phase of $a_i$ are observable, but the global phase of $\psi$ is not:
constraining $a_0$ to be real (or, arbitrarily, imaginary) does not change the
physical meaning of $\psi$. That leaves us with $2^{n+1} - 2$ degrees of
freedom.&lt;/p&gt;
&lt;h3&gt;Visualising qubit state&lt;/h3&gt;
&lt;p&gt;We can visualise a single qubit's state on a unit sphere, known as the Bloch
sphere:&lt;/p&gt;
&lt;figure&gt;
    &lt;p align="center"&gt;
    &lt;img src="images/qc-intro/bloch.svg" alt="The Bloch sphere"&gt;
    &lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;The qubit's &lt;em&gt;state vector&lt;/em&gt; always has magnitude one, hence it always touches the
surface of the unit sphere. The angles $\theta$ and $\phi$ are one way of
expressing our two degrees of freedom. We can write:&lt;/p&gt;
&lt;p&gt;$$
\ket{0} = \begin{bmatrix}
           1 \\
           0
         \end{bmatrix} \equiv \begin{bmatrix}
                          \cos\frac{\theta}{2} \\
                          0
                          \end{bmatrix}
$$&lt;/p&gt;
&lt;p&gt;$$
\ket{1} = \begin{bmatrix}
           0 \\
           1
         \end{bmatrix} \equiv \begin{bmatrix}
                          0 \\
                          e^{i\phi}\sin\frac{\theta}{2}
                          \end{bmatrix}
$$&lt;/p&gt;
&lt;p&gt;We will call the states $\ket{0}$ and $\ket{1}$ our &lt;em&gt;computational basis&lt;/em&gt;, or
simply our &lt;em&gt;basis states&lt;/em&gt;.&lt;/p&gt;
&lt;h4&gt;But what about visualising multiple qubits?&lt;/h4&gt;
&lt;p&gt;The Bloch sphere gives us a convenient way of visualising the state of a single
qubit, but what about multiple qubits? As previously described, if there is no
entanglement, then the state of a multi-qubit system can be factored into
separate individual qubit states. In that case, we can visualise the state of
$n$ qubits on $n$ Bloch spheres. If there is entanglement, we cannot factor our
many-dimensional state into multiple 2-dimensional states, and so visualisation
can be challenging. We won't provide any visualisations here, but there are
several proposed methods&lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;sup id="fnref:5"&gt;&lt;a class="footnote-ref" href="#fn:5"&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3&gt;Manipulating qubit state&lt;/h3&gt;
&lt;p&gt;Now that we can visualise a single qubit's state on the Bloch Sphere, we can
more easily imagine that state being manipulated. What would it mean for the
state vector to be aligned with the positive $x$ axis? That's $90^{\circ}$
rotated around the $y$ axis from either of our basis states. So it's half way
between them!  This is &lt;em&gt;superposition&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;
    &lt;p align="center"&gt;
    &lt;img src="images/qc-intro/superposition.svg" id="superposition"&gt;
    &lt;figcaption&gt;&lt;p align="center"&gt;&lt;i&gt;Superposition on the Bloch sphere&lt;/i&gt;&lt;/p&gt;&lt;/figcaption&gt;
    &lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;We can write the state vector in terms of $\ket{0}$ and $\ket{1}$:&lt;/p&gt;
&lt;p&gt;$$
\ket{\psi} = \frac{1}{\sqrt{2}}\left(\ket{0} + \ket{1}\right)
$$&lt;/p&gt;
&lt;p&gt;Remember, the square magnitude of the coefficients of the basis states gives us
the probability of measuring them. In this case,
$\left|\frac{1}{\sqrt{2}}\right|^2 = \frac{1}{2}$: we have an equal probability
of measuring either $0$ or $1$.&lt;/p&gt;
&lt;p&gt;Manipulating qubit state is also described as executing a &lt;em&gt;quantum logic gate&lt;/em&gt;,
or &lt;em&gt;gate&lt;/em&gt; for short. We can write a matrix operator for a gate that would take
a qubit from $\ket{0}$ to the superposed state shown in &lt;a href="#superposition"&gt;the images
above&lt;/a&gt; (although via a different rotation than described
above):&lt;/p&gt;
&lt;p&gt;$$
\frac{1}{\sqrt{2}}\begin{bmatrix}
       1 &amp;amp; 1 \\
       1 &amp;amp; -1
     \end{bmatrix}\ket{0} = \frac{1}{\sqrt{2}}\left(\ket{0} + \ket{1}\right)
$$&lt;/p&gt;
&lt;p&gt;This gate is known as the Hadamard gate, is shown graphically as a square with
an H in it:&lt;/p&gt;
&lt;p align="center"&gt;
&lt;img src="images/qc-intro/hadamard.svg" style="width: 30%"&gt;
&lt;/p&gt;

&lt;h3&gt;Creating entanglement&lt;/h3&gt;
&lt;p&gt;Let's demonstrate how entanglement is created between two qubits. Similar to
our &lt;a href="#for-a-single-qubit"&gt;single&lt;/a&gt; and &lt;a href="#for-multiple-qubits"&gt;multi-qubit&lt;/a&gt;
equations above, if we have two qubits we can write:&lt;/p&gt;
&lt;p&gt;$$
\ket{\psi} = a_0\ket{00} + a_1\ket{01} + a_2\ket{10} + a_3\ket{11}
$$&lt;/p&gt;
&lt;p&gt;Where e.g. $a_1$ is the probability amplitude associated with measuring $0$
for the first qubit and $1$ for the second. How would we find the coefficients
${a_0,a_1,a_2,a_3}$ given the state vectors of the individual
qubits? For two qubits $c$ and $t$:&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
\ket{\psi_c} &amp;amp;= c_0 \ket{0} + c_1 \ket{1} \\
\ket{\psi_t} &amp;amp;= t_0 \ket{0} + t_1 \ket{1}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;we compute the state vector $\ket{\psi}$ of the two qubit system using the
tensor product of the individual qubits' state vectors:&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
\ket{\psi} &amp;amp;= \ket{\psi_c} \otimes \ket{\psi_t} \\
        &amp;amp;= \begin{bmatrix}
            c_0 \\
            c_1
           \end{bmatrix}
           \otimes
           \begin{bmatrix}
            t_0 \\
            t_1
           \end{bmatrix} \\
        &amp;amp;= \begin{bmatrix}
            c_0 t_0 \\
            c_0 t_1 \\
            c_1 t_0 \\
            c_1 t_1
           \end{bmatrix}
        = \begin{bmatrix}
            a_0 \\
            a_1 \\
            a_2 \\
            a_3
           \end{bmatrix}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;We can now apply two-qubit operators to this vector, in the same way we applied
the Hadamard gate matrix to the single qubit state vector. The &lt;em&gt;controlled NOT&lt;/em&gt;
or &lt;em&gt;CNOT&lt;/em&gt; gate operates on two qubits: a control qubit ($c$) and a target qubit
($t$). It is defined by this matrix:&lt;/p&gt;
&lt;p&gt;$$
CNOT = \begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0
\end{bmatrix}
$$&lt;/p&gt;
&lt;p&gt;and performs this transformation:&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
&amp;amp;a_0\ket{00} + a_1\ket{01} + a_2\ket{10} + a_3\ket{11} \\
\rightarrow \hspace{0.5em} &amp;amp;a_0\ket{00} + a_1\ket{01} + a_3\ket{10} + a_2\ket{11}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;In other words, the probability amplitudes for the measurement outcomes
$\ket{10}$ and $\ket{11}$ are swapped. If the control qubit is purely
$\ket{1}$, then the target qubit is flipped. If the control qubit is purely
$\ket{0}$, then $a_2$ and $a_3$ equal $0$, and there is no effect. If the
controls qubit is in superposition, then the effect on the target qubit will be
correspondingly superposed.&lt;/p&gt;
&lt;p&gt;Let's apply a CNOT gate to our qubits $c$ (for control) and $t$ (for target):&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
\psi &amp;amp;=
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0
\end{bmatrix}
\begin{bmatrix}
 c_0 t_0 \\
 c_0 t_1 \\
 c_1 t_0 \\
 c_1 t_1
\end{bmatrix}
&amp;amp;=
\begin{bmatrix}
 c_0 t_0 \\
 c_0 t_1 \\
 c_1 t_1 \\
 c_1 t_0
\end{bmatrix}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;If $C$ is $\ket{0}$, then ${c_0, c_1} = {1, 0}$:&lt;/p&gt;
&lt;p&gt;$$
\psi = \begin{bmatrix}
 t_0 \\
 t_1 \\
 0 \\
 0
\end{bmatrix}
$$&lt;/p&gt;
&lt;p&gt;and if $C$ is $\ket{1}$, then ${c_0, c_1} = {0, 1}$:&lt;/p&gt;
&lt;p&gt;$$
\psi = \begin{bmatrix}
 0 \\
 0 \\
 t_1 \\
 t_0
\end{bmatrix}
$$&lt;/p&gt;
&lt;p&gt;By inspection, we can see that these are factorisable into separate qubit
states:&lt;/p&gt;
&lt;p&gt;$$
\begin{aligned}
\begin{bmatrix}
 1 \\
 0
\end{bmatrix} \otimes
\begin{bmatrix}
 t_0 \\
 t_1
\end{bmatrix} &amp;amp;=
\begin{bmatrix}
 t_0 \\
 t_1 \\
 0 \\
 0
\end{bmatrix} \\
\begin{bmatrix}
 0 \\
 1
\end{bmatrix} \otimes
\begin{bmatrix}
 t_1 \\
 t_0
\end{bmatrix} &amp;amp;=
\begin{bmatrix}
 0 \\
 0 \\
 t_1 \\
 t_0
\end{bmatrix}
\end{aligned}
$$&lt;/p&gt;
&lt;p&gt;But what if our control qubit $C$ was in superposition? E.g. ${c_0, c_1} =
{\frac{1}{\sqrt{2}}, \frac{1}{\sqrt{2}}}$. If our target qubit is $\ket{0}$
then we get:&lt;/p&gt;
&lt;p&gt;$$
\psi = \begin{bmatrix}
 \frac{1}{\sqrt{2}} \\
 0 \\
 0 \\
 \frac{1}{\sqrt{2}}
\end{bmatrix}
$$&lt;/p&gt;
&lt;p&gt;What happens if we try to factor this into two separate qubit states? Using
a $'$ to denote the new states of the qubits:&lt;/p&gt;
&lt;p&gt;$$
\begin{bmatrix}
 \frac{1}{\sqrt{2}} \\
 0 \\
 0 \\
 \frac{1}{\sqrt{2}}
\end{bmatrix} \stackrel{?}{=}
\begin{bmatrix}
 c_0' t_0' \\
 c_0' t_1' \\
 c_1' t_0' \\
 c_1' t_1'
\end{bmatrix}
$$&lt;/p&gt;
&lt;p&gt;It's not possible for these to be equal: for the first entries and last entries
of each vector to be equal, all of the coefficients $c_0', c_1', t_0', t_1'$
must be non-zero. But for the middle entries of the vectors to be equal, at
least two of the coefficients must be zero. Hence it is not possible for us to
factorise this state vector into two separate qubit states.&lt;/p&gt;
&lt;p&gt;We have created  an &lt;em&gt;entangled state&lt;/em&gt;. We can only describe the state of the
two qubit system: we cannot meaningfully describe the qubits separately.&lt;/p&gt;
&lt;h2&gt;How do you actually make a qubit?&lt;/h2&gt;
&lt;p&gt;Making a quantum computer requires extremely fine control of the quantum state.
The larger an object is, the harder that control becomes. Even a simple
molecule presents challenges, as the state is affected by minute changes in the
relative position of its component atoms due to thermal vibration.&lt;/p&gt;
&lt;p&gt;There are a variety of different qubit types used, but we'll use &lt;a href="https://en.wikipedia.org/wiki/Trapped-ion_quantum_computer"&gt;trapped
ions&lt;/a&gt; as an example
below.&lt;/p&gt;
&lt;h3&gt;Trapped ion qubits&lt;/h3&gt;
&lt;h4&gt;What do $\ket{0}$ and $\ket{1}$ correspond to physically?&lt;/h4&gt;
&lt;p&gt;In a trapped ion qubit, we map discrete excitation states of an ion to our
computational basis states $\ket{0}$ and $\ket{1}$. Which excitation states you
choose depends on various properties, including how stable the states are, and
how they can be measured. We'll give an example below of a specific
architecture that might be used.&lt;/p&gt;
&lt;h4&gt;How do we measure the qubits to get the output of our computation?&lt;/h4&gt;
&lt;p&gt;As an example, let's take single-charge ions of an element from Group 2 of the
periodic table. Neutral atoms would have 2 electrons in their outermost
electron shell, so our +1 charge ions have a single electron in that shell.
In the below diagram, the labelled horizontal lines are energy levels (e.g.
S1/2) of this electron, increasing in energy vertically. Each of the letters
(S, P, D) represent an electron sub-shell, and the numbers are a measure of
momentum.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    P1/2____________________
               )     ^
              (      |
               )     |               ________________________D5/2
              (      |                   (          ^
               )     |                    )         |
              (      |                   (          |
               )     |                    )         |
              (      |                   (          |
               )     |                    )         |
    S1/2_______v_____v____________________v_________v________S1/2
         |                       |                         |
         |   fluorescence        |       shelving and      |
         |   cycle               |       de-shelving       |
         |_______________________|_________________________|

     )                        ^
    (  = spontaneous decay    | = laser-driven
     v                        v
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Within each energy level there are multiple excitation states. For ions with
no nuclear spin, there are two states in S1/2, which correspond to the two
possible spin states of the electron. If we map our computational bases
$\ket{0}$ and $\ket{1}$ to these two states, how could we then measure the
result at the end of our computation?&lt;/p&gt;
&lt;p&gt;When ions decay from a higher energy state to a lower energy state, the lost
energy is emitted as a photon. Photons are something we can measure. In our
example, both of our computational basis states are in S1/2. We can make the
ions fluoresce by hitting them with a laser with the appropriate wavelength to
drive transitions between P1/2 and S1/2. The laser drives transitions in both
directions, so if we keep the laser on, the ions will continuously swap between
P1/2 and S1/2, emitting photons when they move from the higher energy state to
the lower.&lt;/p&gt;
&lt;p&gt;However, because both of our computational bases are in S1/2, we won't be able
to differentiate between measuring a 0 and a 1! The properties of this
transition are such that it's not feasible to have a laser that could select
one of our two states within S1/2. Luckily, the transitions between S1/2 and
D5/2 can be driven selectively. So, prior to measurement we "shelve" by mapping
one of our bases only to an excitation state in D5/2. Measurement is then done
when inducing fluorescence: this is when we get a final 0 or 1 measurement out
from each qubit. The ions will be in a superposition of a state in S1/2 and a
state in D5/2. Some will be measured to have been in S1/2 (as these will
fluoresce, which we measure as 1) and others will be in D5/2 (as these will not
fluoresce, which we measure as 0).&lt;/p&gt;
&lt;p&gt;The D5/2 is stable enough for us to keep the ions there until we've collected
enough photons to make a measurement. We can tune our light detection to
photons of the frequency that will be emitted by P1/2 -&amp;gt; S1/2 transitions, so
that other spontaneous decay does not affect our measurements.&lt;/p&gt;
&lt;h2&gt;Will quantum computers replace classical computers?&lt;/h2&gt;
&lt;p&gt;Quantum computers are only well-suited to certain classes of problems, so I
don't think it's likely that they'd replace classical computers. The goal is to
enable solving of computational problems we can't solve today, not to solve the
same problems with a new kind of computation.&lt;/p&gt;
&lt;h2&gt;Are quantum computers useful?&lt;/h2&gt;
&lt;p&gt;Not yet! Lol.&lt;/p&gt;
&lt;p&gt;But hopefully they will one day enable us to do useful things we can't do
today. The most exciting one for me is that quantum computers should enable
more simulation of quantum mechanics, which in turn will enable better drug
discovery.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;i.e. not used for error correction&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://arxiv.org/abs/quant-ph/0205095"&gt;https://arxiv.org/abs/quant-ph/0205095&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a href="https://www.quantinuum.com/news/quantinuum-extends-its-significant-lead-in-quantum-computing-achieving-historic-milestones-for-hardware-fidelity-and-quantum-volume"&gt;https://www.quantinuum.com/news/quantinuum-extends-its-significant-lead-in-quantum-computing-achieving-historic-milestones-for-hardware-fidelity-and-quantum-volume&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://arxiv.org/pdf/2305.07596"&gt;https://arxiv.org/pdf/2305.07596&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;&lt;a href="https://algassert.com/post/1716"&gt;https://algassert.com/post/1716&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 5 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/></entry><entry><title>Designing a RISC-V CPU, Part 2: Successfully executing (some) instructions</title><link href="https://mcla.ug/risc-v-cpu-part-2.html" rel="alternate"/><published>2021-03-01T00:00:00+00:00</published><updated>2021-03-01T00:00:00+00:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2021-03-01:/risc-v-cpu-part-2.html</id><summary type="html">&lt;p&gt;The &lt;a href="https://mcla.ug/blog/risc-v-cpu-part-1.html"&gt;previous instalment&lt;/a&gt; of this
series was "basically an explanation of what FPGAs are and a 'hello world'
nMigen example."&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; In this post, I will be detailing the design of my CPU as
it currently stands, and going over the various mistakes I made along the way.
As with …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The &lt;a href="https://mcla.ug/blog/risc-v-cpu-part-1.html"&gt;previous instalment&lt;/a&gt; of this
series was "basically an explanation of what FPGAs are and a 'hello world'
nMigen example."&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; In this post, I will be detailing the design of my CPU as
it currently stands, and going over the various mistakes I made along the way.
As with the previous post, I am primarily aiming this at software engineers who
are new to hardware design &amp;ndash; but I hope it will be interesting to anyone
interested in nMigen, RISC-V, or CPU design generally.&lt;/p&gt;
&lt;p&gt;I hope the mistakes I made along the way will be a useful frame for considering
these questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;What about digital logic design is fundamentally different from software
  design?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What about digital logic design is similar to software design?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can see the code for my CPU at the time of writing
&lt;a href="https://github.com/lochsh/riscy-boi/tree/33229b5fdcee90cfdf776ccf925f560f0fa5ce82"&gt;here&lt;/a&gt;
or an up to date version &lt;a href="https://github.com/lochsh/riscy-boi"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;An introduction to RISC-V&lt;/h2&gt;
&lt;p&gt;RISC-V ("risk five") is an open standard instruction set architecture (ISA).
"RISC" means "reduced instruction set computer", broadly meaning that the
ISA prioritises simple instructions. In contrast, CISC (complex instruction set
computer) ISAs are optimised to perform actions in as few instructions as
possible, hence their instructions are often more complex. ARM architectures
are RISC; x86-related architectures are CISC.&lt;/p&gt;
&lt;p&gt;Usually in industry, ISAs are patented, so in order to implement the ISA you
need an (expensive) license from the vendor. Often, commercial ISAs are poorly
documented, with the motivation behind design details not always being
available even after such a license agreement.&lt;/p&gt;
&lt;p&gt;From the RISC-V spec &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our goals in defining RISC-V include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A completely &lt;em&gt;open&lt;/em&gt; ISA that is freely available to academia and industry&lt;/li&gt;
&lt;li&gt;a &lt;em&gt;real&lt;/em&gt; ISA suitable for direct native hardware implementation, not just
simulation or binary translation.&lt;/li&gt;
&lt;li&gt;An ISA that avoids "over-architecting" for a particular microarchitecture
style, but which allows efficient implementation in any of these.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Additionally, a lot of commercial architectures are complex and burdened with
backwards-compatibility constraints. RISC-V offers a fresh start!&lt;/p&gt;
&lt;p&gt;The ISA doesn't explain the details of how to design a CPU &amp;ndash; it just
defines an abstract model of the CPU, mostly by defining what instructions the
CPU must support, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The encoding of the instructions (i.e. how to construct the machine code that
  the CPU will run)&lt;/li&gt;
&lt;li&gt;The registers (the very fast, very small storage locations accessed directly
  by the CPU)&lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How to actually create a CPU that realises these requirements is up to us \o/&lt;/p&gt;
&lt;h3&gt;A quick note (feel free to skip if you don't have opinions about CPUs)&lt;/h3&gt;
&lt;p&gt;I'm trying to design a single-stage CPU; that is, I'm trying to design a CPU
that retires one instruction per clock cycle with no pipelining.  Usually CPUs
have pipelining in place to maximise efficiency. I am hoping that avoiding this
will result in a simpler design more suitable to my learning. Perhaps it will
complicate other aspects of the design (like my program counter having 3
outputs), but I'm certainly finding it easier to hold the design in my
head when I only have to think about this clock cycle and the next. I will
likely discuss this in more detail in the next blog post where I implement the
load instructions. I have a plan for how to make these work in a single cycle,
but they do pose a particular challenge and I may change my design as a
consequence.&lt;/p&gt;
&lt;h2&gt;Designing a CPU&lt;/h2&gt;
&lt;p&gt;RISC-V defines various ISA modules; I will be implementing RV32I, the base
32-bit integer instruction set.&lt;/p&gt;
&lt;p&gt;To design my CPU, I first looked at the JAL (jump and link) and the ADDI (add
immediate) instructions, and drew a block diagram of what hardware
would be needed to decode those instructions. I think the ADDI instruction is
easier to grasp if you're not used to thinking about how machine code is
encoded, so we'll start with that. If this all totally foreign to you, you
might enjoy my
&lt;a href="https://mcla.ug/blog/how-to-flash-an-led.html"&gt;introduction to ARM assembly&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Decoding ADDI&lt;/h3&gt;
&lt;p&gt;&lt;img alt="iri" src="/images/integer-register-immediate.png" title="Diagram of instruction encoding for ADDI from RISC-V spec"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ADDI adds the sign-extended 12-bit immediate to register &lt;em&gt;rs1&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let's break some of this down, imagining we're decoding such an instruction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An immediate is analogous to a literal value in source code; the value itself
  is encoded in the instruction, rather than e.g. retrieved from a register.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;opcode&lt;/em&gt; field is the same value for all the instructions listed here. &lt;/li&gt;
&lt;li&gt;Once we've read the &lt;em&gt;opcode&lt;/em&gt;, we know that bits 12-14 contain the &lt;em&gt;funct3&lt;/em&gt;
  field (3 for 3 bits), which encodes whether this is an ADDI instruction (or
  SLTI, ANDI &amp;amp;c.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, somehow we will have to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Retrieve the value stored in register &lt;em&gt;rs1&lt;/em&gt;&lt;ul&gt;
&lt;li&gt;Therefore, our register file needs an input for selecting this register
  to read, and an output for the data read from that register.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Add that to the immediate value&lt;ul&gt;
&lt;li&gt;An arithmetic logic unit (ALU) will be helpful&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Store the result in register &lt;em&gt;rd&lt;/em&gt;&lt;ul&gt;
&lt;li&gt;Our register file also needs write select and write data inputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sign-extension will be necessary too &amp;ndash; this is just the process of
taking a number narrower than (in our case) 32 bits, and filling in the
remaining bits such that two's complement arithmetic will be performed
correctly. I won't include this in the diagram below.&lt;/p&gt;
&lt;p&gt;Implicit in all this is that we'll need some way to retrieve the instruction
itself and pass it to the instruction decoder. The &lt;em&gt;program counter&lt;/em&gt; is
what tells the instruction memory which address to retrieve an instruction
from.&lt;/p&gt;
&lt;p&gt;&lt;img alt="addi" src="/images/addi.png" title="Block diagram showing the necessary connections         between components to implement the ADDI instruction. The instruction         decoder tells the register file to read from rs1 and write to rd. The         data read from rs1 and the immediate are inputs to the ALU. The output         of the ALU is written to rd. The program counter tells the instruction         memory which address to retrieve and instruction from, and the         instruction memory provides that instruction to the instruction         decoder."&gt;&lt;/p&gt;
&lt;p&gt;I'm using thick cyan lines for data flow and thin magenta lines for control
flow.&lt;/p&gt;
&lt;h3&gt;JAL&lt;/h3&gt;
&lt;p&gt;Now let's try doing the same for JAL.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The jump and link (JAL) instruction [...] immediate encodes a signed offset
in multiples of 2 bytes. The offset is sign-extended and added to the &lt;code&gt;pc&lt;/code&gt; to
form the jump target address. [...] JAL stores the address of the instruction
following the jump (&lt;code&gt;pc&lt;/code&gt; + 4) into register &lt;em&gt;rd&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There's a lot more going on here, particularly if you aren't familiar with
machine code. We noted above that the program counter sets which instruction
will be executed next. Usually the program counter simply increments to the
next address each cycle &amp;ndash; that's how we continue to execute our program!
However, say our program calls a subroutine stored elsewhere in memory; we'd
need a way to &lt;em&gt;jump&lt;/em&gt; to the subroutine address. Or, say we wanted an infinite
loop (ubiquitous in embedded software!); we'd need a way to &lt;em&gt;jump&lt;/em&gt;&lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;4&lt;/a&gt;&lt;/sup&gt; back to
the address at the start of the loop. JAL allows for these situations.&lt;/p&gt;
&lt;p&gt;The "link" part of JAL is the part where the next instruction is stored in the
destination register. This is convenient when the jump is used to execute a
subroutine: once the subroutine completes, we can jump back to that stored
instruction address.&lt;/p&gt;
&lt;p&gt;Here's the encoding for JAL:&lt;/p&gt;
&lt;p&gt;&lt;img alt="jal-enc" src="/images/jal-enc.png" title="Diagram of instruction encoding for JAL from RISC-V spec"&gt;&lt;/p&gt;
&lt;p&gt;Note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The opcode uniquely defines the JAL instruction (no other instructions share
  this opcode)&lt;/li&gt;
&lt;li&gt;We need to unshuffle the immediate to get the offset&lt;/li&gt;
&lt;li&gt;The LSB&lt;sup id="fnref:5"&gt;&lt;a class="footnote-ref" href="#fn:5"&gt;5&lt;/a&gt;&lt;/sup&gt; of the immediate is not encoded because it must be 0: only
  offsets in multiples of 2 bytes are supported.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The unshuffling caused me some pain in my code, so it's amusing to me that it
won't be part of the block diagram below. But it's part of the internals of the
instruction decoder, not its interface, which is what we are determining with
these diagrams. The shuffled bits might seem nonsensical, but they're chosen to
maximise overlap with other instruction formats in RISC-V.&lt;/p&gt;
&lt;p&gt;&lt;img alt="jal" src="/images/jal.png" title="Block diagram showing the necessary connections         between components to implement the JAL instruction."&gt;&lt;/p&gt;
&lt;h3&gt;Putting ADDI and JAL together&lt;/h3&gt;
&lt;p&gt;The next challenge is to draw a block diagram that implements both ADDI and
JAL. The first obvious problem: the inputs to the ALU are different in both
cases, as is the wiring of the output. We need some kind of logic block that
can pick between them depending on some control signal: a multiplexer (mux).&lt;/p&gt;
&lt;p&gt;We also need a way to tell the program counter whether the next instruction
address should come from a set address or from incrementing the current
address.&lt;/p&gt;
&lt;p&gt;Here's what my design looks like at the moment (excluding a few things I have
because I know I'll need them later, like two read select/data signals on the
register file):&lt;/p&gt;
&lt;p&gt;&lt;img alt="mux" src="/images/mux.png" title="Block diagram showing the necessary connections         between components to implement the JAL and ADDI instructions."&gt;&lt;/p&gt;
&lt;h2&gt;Implementing the design&lt;/h2&gt;
&lt;p&gt;As covered in my previous blog post, I'm using
&lt;a href="https://github.com/nmigen/nmigen"&gt;nMigen&lt;/a&gt; to implement my design. As I'm
currently designing a single-stage CPU, more of my design is
combinatorial, rather than synchronous, because I don't require the additional
state that pipelining necessitates. This most likely means my design is
unable to run quickly, but that's not a concern of mine.&lt;/p&gt;
&lt;p&gt;I don't think it's helpful to post all the source code of my implementation in
this blog, but I will include some code here to illustrate mistakes that I made
and what I learned from them.&lt;/p&gt;
&lt;h3&gt;Mistake #1: thinking about my logic circuit sequentially&lt;/h3&gt;
&lt;p&gt;I initially implemented my program counter incorrectly after I got really
confused about when synchronous updates would take effect. I initially only had
the &lt;code&gt;pc&lt;/code&gt; and &lt;code&gt;pc_inc&lt;/code&gt; outputs because I didn't really understand the difference
between &lt;code&gt;pc&lt;/code&gt; and &lt;code&gt;pc_next&lt;/code&gt;.  It's taken some getting used to thinking about the
whole logic circuit "happening at once"&lt;sup id="fnref:7"&gt;&lt;a class="footnote-ref" href="#fn:7"&gt;7&lt;/a&gt;&lt;/sup&gt;, rather thinking sequentially like
I would when writing software.  This is what led to my confusion. Properly
conceptualising your circuit in this way is key, and a challenge if you're used
to writing software.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;Program Counter&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; nmigen &lt;span class="Statement"&gt;as&lt;/span&gt; nm
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;INSTR_BYTES &lt;span class="op_lv0"&gt;=&lt;/span&gt; &lt;span class="Number"&gt;4&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;&lt;span class="Statement"&gt;class&lt;/span&gt; &lt;span class="Function"&gt;ProgramCounter&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;nm&lt;span class="op_lv12"&gt;.&lt;/span&gt;Elaboratable&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    &lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;&lt;span class="String"&gt;    Program Counter&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;&lt;span class="String"&gt;    * load (in): low to increment, high to load an address&lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;&lt;span class="String"&gt;    * input_address (in): the input used when loading an address&lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;&lt;span class="String"&gt;    * pc (out): the address of the instruction being executed this clock cycle&lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;&lt;span class="String"&gt;    * pc_next (out): the address of the instruction being executed next clock&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;&lt;span class="String"&gt;      cycle&lt;/span&gt;
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;&lt;span class="String"&gt;    * pc_inc (out): the address after that of the instruction being executed&lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;&lt;span class="String"&gt;      this clock cycle&lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;&lt;span class="String"&gt;    &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;    &lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;__init__&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;,&lt;/span&gt; width&lt;span class="op_lv12"&gt;=&lt;/span&gt;&lt;span class="Number"&gt;32&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;        self&lt;span class="op_lv0"&gt;.&lt;/span&gt;load &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Signal&lt;span class="lv12c"&gt;()&lt;/span&gt;
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;        self&lt;span class="op_lv0"&gt;.&lt;/span&gt;input_address &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Signal&lt;span class="lv12c"&gt;(&lt;/span&gt;width&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;        self&lt;span class="op_lv0"&gt;.&lt;/span&gt;pc &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Signal&lt;span class="lv12c"&gt;(&lt;/span&gt;width&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;        self&lt;span class="op_lv0"&gt;.&lt;/span&gt;pc_next &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Signal&lt;span class="lv12c"&gt;(&lt;/span&gt;width&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L26" class="LineNr"&gt;26 &lt;/span&gt;        self&lt;span class="op_lv0"&gt;.&lt;/span&gt;pc_inc &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Signal&lt;span class="lv12c"&gt;(&lt;/span&gt;width&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L27" class="LineNr"&gt;27 &lt;/span&gt;
&lt;span id="L28" class="LineNr"&gt;28 &lt;/span&gt;    &lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;elaborate&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;,&lt;/span&gt; _&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L29" class="LineNr"&gt;29 &lt;/span&gt;        m &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Module&lt;span class="lv12c"&gt;()&lt;/span&gt;
&lt;span id="L30" class="LineNr"&gt;30 &lt;/span&gt;
&lt;span id="L31" class="LineNr"&gt;31 &lt;/span&gt;        m&lt;span class="op_lv0"&gt;.&lt;/span&gt;d&lt;span class="op_lv0"&gt;.&lt;/span&gt;comb &lt;span class="op_lv0"&gt;+=&lt;/span&gt; self&lt;span class="op_lv0"&gt;.&lt;/span&gt;pc_inc&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;.&lt;/span&gt;pc &lt;span class="op_lv12"&gt;+&lt;/span&gt; INSTR_BYTES&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L32" class="LineNr"&gt;32 &lt;/span&gt;        m&lt;span class="op_lv0"&gt;.&lt;/span&gt;d&lt;span class="op_lv0"&gt;.&lt;/span&gt;sync &lt;span class="op_lv0"&gt;+=&lt;/span&gt; self&lt;span class="op_lv0"&gt;.&lt;/span&gt;pc&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;.&lt;/span&gt;pc_next&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L33" class="LineNr"&gt;33 &lt;/span&gt;
&lt;span id="L34" class="LineNr"&gt;34 &lt;/span&gt;        &lt;span class="Statement"&gt;with&lt;/span&gt; m&lt;span class="op_lv0"&gt;.&lt;/span&gt;If&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;.&lt;/span&gt;load&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L35" class="LineNr"&gt;35 &lt;/span&gt;            m&lt;span class="op_lv0"&gt;.&lt;/span&gt;d&lt;span class="op_lv0"&gt;.&lt;/span&gt;comb &lt;span class="op_lv0"&gt;+=&lt;/span&gt; self&lt;span class="op_lv0"&gt;.&lt;/span&gt;pc_next&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;.&lt;/span&gt;input_address&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L36" class="LineNr"&gt;36 &lt;/span&gt;        &lt;span class="Statement"&gt;with&lt;/span&gt; m&lt;span class="op_lv0"&gt;.&lt;/span&gt;Else&lt;span class="lv12c"&gt;()&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L37" class="LineNr"&gt;37 &lt;/span&gt;            m&lt;span class="op_lv0"&gt;.&lt;/span&gt;d&lt;span class="op_lv0"&gt;.&lt;/span&gt;comb &lt;span class="op_lv0"&gt;+=&lt;/span&gt; self&lt;span class="op_lv0"&gt;.&lt;/span&gt;pc_next&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;.&lt;/span&gt;pc_inc&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L38" class="LineNr"&gt;38 &lt;/span&gt;
&lt;span id="L39" class="LineNr"&gt;39 &lt;/span&gt;        &lt;span class="Statement"&gt;return&lt;/span&gt; m
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;When thinking about my implementation, I now want to answer these questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is my state?&lt;/li&gt;
&lt;li&gt;How are the outputs computed?&lt;/li&gt;
&lt;li&gt;How is the state updated?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This sounds simple, but it has been clarifying. For this case:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pc&lt;/code&gt; is my state (you'll note it is assigned synchronously, so its value
  is updated at the start of the next clock cycle).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pc&lt;/code&gt;, &lt;code&gt;pc_inc&lt;/code&gt;, and &lt;code&gt;pc_next&lt;/code&gt; are the outputs:&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;pc&lt;/code&gt; output is the current state&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pc_inc&lt;/code&gt; is just &lt;code&gt;pc + 4&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pc_next&lt;/code&gt; swaps between &lt;code&gt;pc_inc&lt;/code&gt; and the &lt;code&gt;input_address&lt;/code&gt; based on load&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Each clock cycle, &lt;code&gt;pc&lt;/code&gt; takes on the value of &lt;code&gt;pc_next&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Mistake #2: Creating a combinatorial loop&lt;/h3&gt;
&lt;p&gt;This isn't really an additional mistake, as the incorrect program counter
implementation described above caused this. I felt this particular consequence
deserved its own subsection.&lt;/p&gt;
&lt;p&gt;When I only had the &lt;code&gt;pc&lt;/code&gt; and &lt;code&gt;pc_inc&lt;/code&gt; outputs from my program counter, I
created the following combinatorial loop:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;pc&lt;/code&gt; output was an input to the ALU&lt;/li&gt;
&lt;li&gt;but the &lt;code&gt;pc&lt;/code&gt; output was computed from the output of the ALU&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both of these signals were in the combinatorial domain, so they were
effectively wired together in a loop.&lt;/p&gt;
&lt;p&gt;The creation of this feedback loop resulted in my tests hanging as my
combinatorial simulations never settled. If I'd tried to synthesise my design,
the synthesis tools would have refused. If you were able to synthesise such a
design, the output would be constantly changing.&lt;/p&gt;
&lt;h3&gt;Mistake #3: Not creating the block diagram correctly&lt;/h3&gt;
&lt;p&gt;True Fans™ of this blog might notice that the block diagram above has a
notable difference from the one shown at the end of the previous blog post:
previously I didn't mux the input of the ALU. I was wondering why JAL wasn't
working, and tried to trace it through my block diagram, like we did above. A
re-enactment:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Computer, show my original sketch of the block diagram.&lt;/em&gt;
&lt;img alt="sketch" src="/images/block-diagram-sktech.jpg" title="A screenshot of my first CPU design sketch"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Computer, enhance:&lt;/em&gt;
&lt;img alt="enhance" src="/images/enhance.jpg" title="Zoomed into a note on screenshot saying 'need to multiplex ALU input"&gt;&lt;/p&gt;
&lt;p&gt;Me:
&lt;img alt="pikachu" src="/images/shocked-pikachu.png" title="Shocked pikachu face from Pokemon"&gt;&lt;/p&gt;
&lt;p&gt;The above is a bit frivolous, but I'd say the lesson here is to think actively
about your block diagram (or whatever reference you are using while
implementing your design), making sure it actually makes sense to you and does
what you want it to. This applies to software design too when viewing any
requirements or other design documentation, of course.&lt;/p&gt;
&lt;h3&gt;Miscellaneous mistakes&lt;/h3&gt;
&lt;p&gt;I made a lot of other mistakes that aren't that interesting to cover &amp;ndash;
most notably really messing up the unshuffling of the immediate in the JAL
instruction. But that was just a programming error without an interesting
lesson to be learnt from it.&lt;/p&gt;
&lt;h2&gt;Running my first program!&lt;/h2&gt;
&lt;p&gt;It was a very exciting moment when I figured out the last of the mistakes I had
made in my implementation, with the help of my tests and of gtkwave.&lt;/p&gt;
&lt;p&gt;For convenience in tests, my instruction decoding code also has code for
assembling instructions. I use it here to create a simple program with two
instructions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An &lt;code&gt;ADDI&lt;/code&gt; instruction where &lt;code&gt;rd&lt;/code&gt; and &lt;code&gt;rs1&lt;/code&gt; are the same register, and the
  immediate is &lt;code&gt;1&lt;/code&gt;. This means it will increment the value in &lt;code&gt;rs1&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;code&gt;JAL&lt;/code&gt; instruction with an offset of -4, meaning it jumps back to our &lt;code&gt;ADDI&lt;/code&gt;
  instruction. This creates an infinite loop where the value in a register is
  incremented each clock cycle.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The LED code is specific to my board. I'm selecting 4 bits (one for each LED)
in the register and displaying them on the board's LEDs. I pick bits in the
middle so they don't change too quickly to see (as would be the case if I
picked the LSBs) or too slow to look cool (as would be the case if I picked the
MSBs).&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;        program &lt;span class="op_lv0"&gt;=&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;encoding&lt;span class="op_lv12"&gt;.&lt;/span&gt;IType&lt;span class="op_lv12"&gt;.&lt;/span&gt;encode&lt;span class="lv11c"&gt;(&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;                        &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;                        reg&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;                        encoding&lt;span class="op_lv11"&gt;.&lt;/span&gt;IntRegImmFunct&lt;span class="op_lv11"&gt;.&lt;/span&gt;ADDI&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;                        reg&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;                        encoding&lt;span class="op_lv11"&gt;.&lt;/span&gt;Opcode&lt;span class="op_lv11"&gt;.&lt;/span&gt;OP_IMM&lt;span class="lv11c"&gt;)&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;                   &lt;span class="Comment"&gt;# jump back to the previous instruction for infinite loop&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;                   encoding&lt;span class="op_lv12"&gt;.&lt;/span&gt;JType&lt;span class="op_lv12"&gt;.&lt;/span&gt;encode&lt;span class="lv11c"&gt;(&lt;/span&gt;&lt;span class="Number"&gt;0x1ffffc&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt; link_reg&lt;span class="lv11c"&gt;)&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;        imem &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Memory&lt;span class="lv12c"&gt;(&lt;/span&gt;width&lt;span class="op_lv12"&gt;=&lt;/span&gt;&lt;span class="Number"&gt;32&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; depth&lt;span class="op_lv12"&gt;=&lt;/span&gt;&lt;span class="Number"&gt;256&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; init&lt;span class="op_lv12"&gt;=&lt;/span&gt;program&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;        imem_rp &lt;span class="op_lv0"&gt;=&lt;/span&gt; m&lt;span class="op_lv0"&gt;.&lt;/span&gt;submodules&lt;span class="op_lv0"&gt;.&lt;/span&gt;imem_rp &lt;span class="op_lv0"&gt;=&lt;/span&gt; imem&lt;span class="op_lv0"&gt;.&lt;/span&gt;read_port&lt;span class="lv12c"&gt;()&lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;        m&lt;span class="op_lv0"&gt;.&lt;/span&gt;d&lt;span class="op_lv0"&gt;.&lt;/span&gt;comb &lt;span class="op_lv0"&gt;+=&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;                imem_rp&lt;span class="op_lv12"&gt;.&lt;/span&gt;addr&lt;span class="op_lv12"&gt;.&lt;/span&gt;eq&lt;span class="lv11c"&gt;(&lt;/span&gt;cpu_inst&lt;span class="op_lv11"&gt;.&lt;/span&gt;imem_addr&lt;span class="lv11c"&gt;)&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;                cpu_inst&lt;span class="op_lv12"&gt;.&lt;/span&gt;imem_data&lt;span class="op_lv12"&gt;.&lt;/span&gt;eq&lt;span class="lv11c"&gt;(&lt;/span&gt;imem_rp&lt;span class="op_lv11"&gt;.&lt;/span&gt;data&lt;span class="lv11c"&gt;)&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;        &lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;        colours &lt;span class="op_lv0"&gt;=&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;b&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;g&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;o&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;r&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;        leds &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Cat&lt;span class="lv12c"&gt;(&lt;/span&gt;platform&lt;span class="op_lv12"&gt;.&lt;/span&gt;request&lt;span class="lv11c"&gt;(&lt;/span&gt;f&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;led_{c}&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="lv11c"&gt;)&lt;/span&gt; &lt;span class="Statement"&gt;for&lt;/span&gt; c &lt;span class="Statement"&gt;in&lt;/span&gt; colours&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;        m&lt;span class="op_lv0"&gt;.&lt;/span&gt;d&lt;span class="op_lv0"&gt;.&lt;/span&gt;sync &lt;span class="op_lv0"&gt;+=&lt;/span&gt; leds&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;cpu_inst&lt;span class="op_lv12"&gt;.&lt;/span&gt;debug_out&lt;span class="lv11c"&gt;[&lt;/span&gt;&lt;span class="Number"&gt;13&lt;/span&gt;&lt;span class="op_lv11"&gt;:&lt;/span&gt;&lt;span class="Number"&gt;17&lt;/span&gt;&lt;span class="lv11c"&gt;]&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;And here is a poor quality gif of the LEDs! Very exciting.
&lt;img alt="leds" src="/images/cpu.gif" title="The LEDs flashing on the FPGA dev board"&gt;&lt;/p&gt;
&lt;p&gt;The next stage will be to implement the rest of the RV32I instructions.
Probably I will start with the load instructions, as I think they will pose a
challenge in my current single-stage architecture. I have a plan for how to
address that. If you'd like to see future instalments of this blog series, you
can follow me on &lt;a href="https://twitter.com/lochsh"&gt;Twitter&lt;/a&gt; or subscribe to my
&lt;a href="https://mcla.ug/blog/feeds/all.rss.xml"&gt;RSS feed&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Differences and commonalities between software design and digital logic design&lt;/h2&gt;
&lt;p&gt;Now that I've completed a lot more of the design and implementation of my CPU,
I have some clearer thoughts on this topic. I thought there would be some
clear differences in kind between software design and digital logic design.
After much thought, I wonder if there are merely differences in degree.&lt;/p&gt;
&lt;h3&gt;Concurrency&lt;/h3&gt;
&lt;p&gt;First, let's consider concurrency. This is a topic that's sometimes
misunderstood, so let's be clear: concurrency happens whenever different
parts of your system might execute at different times or out of order&lt;sup id="fnref:6"&gt;&lt;a class="footnote-ref" href="#fn:6"&gt;6&lt;/a&gt;&lt;/sup&gt;. A
system is concurrent if it can support having multiple tasks in progress at the
same time; this could be in parallel, or it could involve switching between the
tasks while only actually executing one at any given moment.&lt;/p&gt;
&lt;p&gt;Arguably, the default state for software is to have no concurrency &amp;ndash; it
often needs explicitly created (e.g. by creating a thread), or at the very
least, it needs explicitly handled (e.g. in an interrupt handler). I think any
software engineer who has worked on concurrent software would agree that
dealing with concurrency is a singular challenge that creates room for
difficult and subtle bugs. For these two reasons, software generally has
limited concurrency.&lt;/p&gt;
&lt;p&gt;Now imagine concurrency is your default state, and that every single piece of
state is updating all at once every step of your program.&lt;/p&gt;
&lt;p&gt;That is the default state of digital logic. While in software you generally
have to explicitly create (or at least explicitly handle) concurrency, in
hardware you have to deliberately make something sequential.&lt;/p&gt;
&lt;p&gt;I said above that concurrency in software is challenging. If digital hardware
has more concurrency, is it more challenging to design? Perhaps! It's hard for
me to comment on this due to my lack of experience in hardware design.&lt;/p&gt;
&lt;p&gt;Perhaps one reason that concurrency is so difficult in software is the annoying
habit of a lot of software&lt;sup id="fnref:8"&gt;&lt;a class="footnote-ref" href="#fn:8"&gt;8&lt;/a&gt;&lt;/sup&gt; to be dependent on a colossal amount of state.
How many possible states does a mere kilo-bit of memory have? 2^{1024} is too
big a number for me to conceptualise. And yet a kilo-bit is nothing by many
program's standards.&lt;/p&gt;
&lt;p&gt;In hardware, state is more precious. My FPGA is only so large. I have an
ice40hx8k, which has 8000 logic cells. Each cell has one 4-input LUT and one
flip-flop: so let's say 8000 bits of state. Pathetic! Watch me create
millions of bits of pure chaos with a single call to &lt;code&gt;malloc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And of course, if you were designing for silicon, the size of your design would
be directly related to cost!&lt;/p&gt;
&lt;h3&gt;Verification&lt;/h3&gt;
&lt;p&gt;So, we've considered concurrency. Another thing I wondered is whether digital
hardware has some fundamental property that makes it easier to formally verify,
or at least to demonstrate equivalence with a model. When I worked on a system
that could kill people if it malfunctioned, in our risk assessments we had to
assume 100% chance of software failure. Practically this generally meant that
software mitigation alone was not enough. I found it strange that the FPGA
component of our system was considered much more trusted. Did hardware have
some fundamental property that made it "better"?&lt;/p&gt;
&lt;p&gt;Once again, I don't think there &lt;em&gt;is&lt;/em&gt; a fundamental difference here. After all,
software exists that has been formally verified. In general, functional
programming lends itself better to this due to the separation of state and
behaviour. It seems more likely that the difference is in the careful
management of state. The properties of digital hardware described above
encourage this, but it's not impossible to do in software.&lt;/p&gt;
&lt;p&gt;The huge teams of verification engineers that work on silicon design might also
suggest some fundamental difference, given you might not have seen the same
applied to software. However, there &lt;em&gt;are&lt;/em&gt; software projects that are given this
level of rigour! Most famously, much of NASA's software, like software for
space shuttles&lt;sup id="fnref:9"&gt;&lt;a class="footnote-ref" href="#fn:9"&gt;9&lt;/a&gt;&lt;/sup&gt;. The sad truth is that most companies don't consider it
worth it to apply this rigour to their software (it's hugely expensive!). When
sufficient lives and/or money are on the line, software &lt;em&gt;can&lt;/em&gt; and &lt;em&gt;is&lt;/em&gt; written
and tested with the same level of rigour as a lot of hardware..&lt;/p&gt;
&lt;p&gt;If you have thoughts to share on what you think the differences and
commonalities between hardware and software design are, please share them via
&lt;a href="mailto:h@mcla.ug"&gt;email&lt;/a&gt; or in Hacker News comments if you have come from
there. It's been really interesting to ponder, and I'd be interested in
different perspectives.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Hacker News comment, 2021&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf"&gt;https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Just a note: the word "register" is pretty overloaded. You may have heard
it in the context used above (the small storage accessed directly by the CPU);
for memory-mapped IO in a microcontroller; you may have also heard "register"
used as a verb to describe saving state in hardware.&amp;#160;&lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;I think generally "branch" is used to describe conditional instructions,
whereas "jump" is used to describe unconditional instructions. Certainly this
is the case in RISC-V, but I think it very much depends on the particular
architecture, and sometimes they are used interchangeably.&amp;#160;&lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;Least Significant Bit&amp;#160;&lt;a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 5 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;wording from &lt;a href="https://docs.rust-embedded.org/book/concurrency/"&gt;https://docs.rust-embedded.org/book/concurrency/&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:6" title="Jump back to footnote 6 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:7"&gt;
&lt;p&gt;Of course in analogue reality things are not happening at exactly the
same time, but our abstraction is the discrete time period of our clock.&amp;#160;&lt;a class="footnote-backref" href="#fnref:7" title="Jump back to footnote 7 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:8"&gt;
&lt;p&gt;functional programmers, we don't need your smugness here!&amp;#160;&lt;a class="footnote-backref" href="#fnref:8" title="Jump back to footnote 8 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:9"&gt;
&lt;p&gt;&lt;a href="https://www.fastcompany.com/28121/they-write-right-stuff"&gt;https://www.fastcompany.com/28121/they-write-right-stuff&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:9" title="Jump back to footnote 9 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/></entry><entry><title>Designing a RISC-V CPU, Part 1: Learning hardware design as a software engineer</title><link href="https://mcla.ug/risc-v-cpu-part-1.html" rel="alternate"/><published>2021-02-16T00:00:00+00:00</published><updated>2021-02-16T00:00:00+00:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2021-02-16:/risc-v-cpu-part-1.html</id><summary type="html">&lt;p&gt;I have no experience in digital logic design. That is, I didn't until I
recently decided that I would like to try designing my own CPU and running it
on an FPGA! If you too are a software engineer with a vague interest in
hardware design, I hope this series …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have no experience in digital logic design. That is, I didn't until I
recently decided that I would like to try designing my own CPU and running it
on an FPGA! If you too are a software engineer with a vague interest in
hardware design, I hope this series of posts about what I've learnt will be
helpful and interesting. In this first installment, I hope to answer these
questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;What is digital logic design?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How do I get started, and what tools might I use?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In future installments, I will go into more detail about my CPU design and the
RISC-V architecture, as well as hopefully answering these questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;What about digital logic design is fundamentally different from software
  design?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What about digital logic design is similar to software design?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can see the code for my CPU at the time of writing
&lt;a href="https://github.com/lochsh/riscy-boi/tree/47e94dc6e9665f73c871add002c34d1516fd5106"&gt;here&lt;/a&gt;
or an up to date version &lt;a href="https://github.com/lochsh/riscy-boi"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;What is digital logic design?&lt;/h2&gt;
&lt;p&gt;Digital logic design is designing logic circuits that operate on binary values.
The elementary components are logic gates: an AND gate, for example, has two
inputs and one output. The output is 1 iff&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; both inputs are 1.&lt;/p&gt;
&lt;p&gt;Typically, we design synchronous circuits which use flip-flops to store state,
and thereby synchronise the operation of the circuit to a common clock.
Flip-flops are composed of logic gates.&lt;/p&gt;
&lt;p&gt;Analogue circuit design is concerned with the electronic components that make
up logic gates, like transistors and diodes. This level of abstraction is often
needed for applications dealing directly with signals derived from analogue
sensors, like radio receivers. When designing a CPU, this level of abstraction
would not be feasible: modern CPUs can have billions of transistors!&lt;/p&gt;
&lt;p&gt;Instead, we use tools that can translate our digital logic design into
different useful formats: the configuration of an FPGA (see below); a
simulation; silicon layout.&lt;/p&gt;
&lt;h2&gt;What is an FPGA and why are they used?&lt;/h2&gt;
&lt;p&gt;We noted above that the same digital logic design tools can be used whether we
are creating a custom ASIC to be made into silicon, or configuring an FPGA. A
Field-Programmable Gate Array is an integrated circuit containing an array of
programmable logic blocks. You could imagine it is as a big array of logic
gates that can be connected together in various ways.&lt;/p&gt;
&lt;p&gt;Making a custom chip generally costs millions, and of course once your chip is
manufactured it cannot be changed. Thus, generally FPGAs are used when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You cannot afford to create a custom ASIC due to lack of capital (e.g. if
  you're just some hacker like me and not ARM or Intel)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You cannot afford to create a custom ASIC because your volume is too low to
  make it worth the high one-off costs (e.g. if you are making a small quantity
  of MRI machines with custom data acquisition hardware)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You need the flexibility&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The downsides? FPGAs have a much higher per-chip cost, and they are generally
much slower as a consequence of being able to connect logic blocks together in
very flexible ways. In contrast, a custom design can be reduced to the minimum
number of transistors, with no concern for flexibility.&lt;/p&gt;
&lt;p&gt;I think it's helpful context to compare the custom ASIC design process against
that of an FPGA design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style="color:#fc04a2"&gt;Logic design&lt;/span&gt;: just like we'd do for an FPGA, the logic design of an ASIC is
  done in a hardware description language.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style="color:#fc04a2"&gt;Verification&lt;/span&gt;: FPGA designs may well be verified, but you might expect the
  process for an ASIC design to be more rigorous &amp;ndash; after all, the design
  can't be changed once manufactured! Often verification will involve formally
  verifying&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt; parts of the design.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style="color:#fc04a2"&gt;Synthesis&lt;/span&gt;: This creates a &lt;em&gt;netlist&lt;/em&gt;: a list of logic blocks and their
  connections. The connections are called &lt;em&gt;nets&lt;/em&gt;, and the blocks are called
  &lt;em&gt;cells&lt;/em&gt;. For both FPGAs and ASICs, the cells are vendor-specific.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style="color:#fc04a2"&gt;Placement and routing&lt;/span&gt; (P&amp;amp;R): for an FPGA, this involves mapping the logic
  blocks described in the netlist to actual blocks in the FPGA. The resulting
  binary is often called a &lt;em&gt;bitstream&lt;/em&gt;.  For an ASIC, this involves deciding
  where to place the cells on the silicon, and how to connect them up. Both
  applications generally use automated optimisation tools for this.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What tools do I need?&lt;/h2&gt;
&lt;h3&gt;A hardware description language: I am using &lt;a href="https://github.com/nmigen/nmigen"&gt;nMigen&lt;/a&gt;&lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/h3&gt;
&lt;p&gt;You may have heard of Verilog or VHDL: both popular hardware description
languages (HDLs). I use "popular" here to mean widely used, not widely loved.&lt;/p&gt;
&lt;p&gt;I won't pretend to know much about these tools: I only know that smarter people
than me with vast logic design experience have a lot of hate for them.
Due to the problems with Verilog and other similar tools, there have been
various attempts at making more useful and friendlier alternatives.  nMigen is
one such project, which creates a domain-specific language in Python. In their
own words:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Despite being faster than schematics entry, hardware design with Verilog and
VHDL remains tedious and inefficient for several reasons. The event-driven
model introduces issues and manual coding that are unnecessary for
synchronous circuits, which represent the lion's share of today's logic
designs. Counterintuitive arithmetic rules result in steeper learning curves
and provide a fertile ground for subtle bugs in designs. Finally, support for
procedural generation of logic (metaprogramming) through "generate"
statements is very limited and restricts the ways code can be made generic,
reused and organized.&lt;/p&gt;
&lt;p&gt;To address those issues, we have developed the nMigen FHDL, a library that
replaces the event-driven paradigm with the notions of combinatorial and
synchronous statements, has arithmetic rules that make integers always behave
like mathematical integers, and most importantly allows the design's logic to
be constructed by a Python program. This last point enables hardware
designers to take advantage of the richness of the Python language—object
oriented programming, function parameters, generators, operator overloading,
libraries, etc.—to build well organized, reusable and elegant designs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If, like me, you've never used Verilog, then not all of this will have more
than abstract meaning to you. But it certainly sounds promising,
and I can attest that it has been very straightforward to get started with
logic design without the reportedly large barrier of grappling with Verilog. I
would recommend it, particularly if you are already familiar with Python!&lt;/p&gt;
&lt;p&gt;The only downside I can think of is that nMigen is still in development, and
in particular the documentation is not complete. There is a helpful community
at #nmigen on &lt;a href="chat.freenode.net"&gt;chat.freenode.net&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;A wave viewer for inspecting simulations: I am using &lt;a href="http://gtkwave.sourceforge.net/"&gt;GTKWave&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;nMigen provides simulation tooling: I use it in my tests, written using
&lt;code&gt;pytest&lt;/code&gt;. I record the signals during these tests and view them in a wave
viewer to help debug.&lt;/p&gt;
&lt;p&gt;&lt;img alt="gtkwave" src="/images/gtkwave.png" title="A screenshot of GTKWave"&gt;&lt;/p&gt;
&lt;h3&gt;Optional: An FPGA dev board. I am using a myStorm BlackIce II&lt;/h3&gt;
&lt;p&gt;You don't need an FPGA dev board to create your own CPU. You could do
everything in simulation! The fun of having a board to work with, for me, is
being able to flash LEDs and see my design in action.&lt;/p&gt;
&lt;p&gt;Of course, if you were creating something more useful than my very basic CPU,
then you would probably want some hardware to run it on, and this would be less
"optional"!&lt;/p&gt;
&lt;h2&gt;Getting started with nMigen&lt;/h2&gt;
&lt;p&gt;Rather than immediately trying to design a CPU, I started by making an
Arithmetic Logic Unit (ALU) in nMigen. The ALU is a key piece of any CPU design
that I have seen: it performs arithmetic operations.&lt;/p&gt;
&lt;p&gt;Why start with this? I knew I would need an ALU for my CPU; I knew I could make
a simple one; I knew that the feeling of making something is an important
motivator when starting a new project!&lt;/p&gt;
&lt;p&gt;My design looked something like this:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;Arithmetic Logic Unit&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; enum
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; nmigen &lt;span class="Statement"&gt;as&lt;/span&gt; nm
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;&lt;span class="Statement"&gt;class&lt;/span&gt; &lt;span class="Function"&gt;ALUOp&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;enum&lt;span class="op_lv12"&gt;.&lt;/span&gt;IntEnum&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    &lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;Operations for the ALU&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    ADD &lt;span class="op_lv0"&gt;=&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;    SUB &lt;span class="op_lv0"&gt;=&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;&lt;span class="Statement"&gt;class&lt;/span&gt; &lt;span class="Function"&gt;ALU&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;nm&lt;span class="op_lv12"&gt;.&lt;/span&gt;Elaboratable&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;    &lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;&lt;span class="String"&gt;    Arithmetic Logic Unit&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;&lt;span class="String"&gt;    * op (in): the opcode&lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;&lt;span class="String"&gt;    * a (in): the first operand&lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;&lt;span class="String"&gt;    * b (in): the second operand&lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;&lt;span class="String"&gt;    * o (out): the output&lt;/span&gt;
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;&lt;span class="String"&gt;    &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;    &lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;__init__&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;,&lt;/span&gt; width&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;        &lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L26" class="LineNr"&gt;26 &lt;/span&gt;&lt;span class="String"&gt;        Initialiser&lt;/span&gt;
&lt;span id="L27" class="LineNr"&gt;27 &lt;/span&gt;
&lt;span id="L28" class="LineNr"&gt;28 &lt;/span&gt;&lt;span class="String"&gt;        Args:&lt;/span&gt;
&lt;span id="L29" class="LineNr"&gt;29 &lt;/span&gt;&lt;span class="String"&gt;            width (int): data width&lt;/span&gt;
&lt;span id="L30" class="LineNr"&gt;30 &lt;/span&gt;&lt;span class="String"&gt;        &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L31" class="LineNr"&gt;31 &lt;/span&gt;        self&lt;span class="op_lv0"&gt;.&lt;/span&gt;op &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Signal&lt;span class="lv12c"&gt;()&lt;/span&gt;
&lt;span id="L32" class="LineNr"&gt;32 &lt;/span&gt;        self&lt;span class="op_lv0"&gt;.&lt;/span&gt;a &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Signal&lt;span class="lv12c"&gt;(&lt;/span&gt;width&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L33" class="LineNr"&gt;33 &lt;/span&gt;        self&lt;span class="op_lv0"&gt;.&lt;/span&gt;b &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Signal&lt;span class="lv12c"&gt;(&lt;/span&gt;width&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L34" class="LineNr"&gt;34 &lt;/span&gt;        self&lt;span class="op_lv0"&gt;.&lt;/span&gt;o &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Signal&lt;span class="lv12c"&gt;(&lt;/span&gt;width&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L35" class="LineNr"&gt;35 &lt;/span&gt;
&lt;span id="L36" class="LineNr"&gt;36 &lt;/span&gt;    &lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;elaborate&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;,&lt;/span&gt; _&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L37" class="LineNr"&gt;37 &lt;/span&gt;        m &lt;span class="op_lv0"&gt;=&lt;/span&gt; nm&lt;span class="op_lv0"&gt;.&lt;/span&gt;Module&lt;span class="lv12c"&gt;()&lt;/span&gt;
&lt;span id="L38" class="LineNr"&gt;38 &lt;/span&gt;
&lt;span id="L39" class="LineNr"&gt;39 &lt;/span&gt;        &lt;span class="Statement"&gt;with&lt;/span&gt; m&lt;span class="op_lv0"&gt;.&lt;/span&gt;Switch&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;.&lt;/span&gt;op&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L40" class="LineNr"&gt;40 &lt;/span&gt;            &lt;span class="Statement"&gt;with&lt;/span&gt; m&lt;span class="op_lv0"&gt;.&lt;/span&gt;Case&lt;span class="lv12c"&gt;(&lt;/span&gt;ALUOp&lt;span class="op_lv12"&gt;.&lt;/span&gt;ADD&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L41" class="LineNr"&gt;41 &lt;/span&gt;                m&lt;span class="op_lv0"&gt;.&lt;/span&gt;d&lt;span class="op_lv0"&gt;.&lt;/span&gt;comb &lt;span class="op_lv0"&gt;+=&lt;/span&gt; self&lt;span class="op_lv0"&gt;.&lt;/span&gt;o&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;.&lt;/span&gt;a &lt;span class="op_lv12"&gt;+&lt;/span&gt; self&lt;span class="op_lv12"&gt;.&lt;/span&gt;b&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L42" class="LineNr"&gt;42 &lt;/span&gt;            &lt;span class="Statement"&gt;with&lt;/span&gt; m&lt;span class="op_lv0"&gt;.&lt;/span&gt;Case&lt;span class="lv12c"&gt;(&lt;/span&gt;ALUOp&lt;span class="op_lv12"&gt;.&lt;/span&gt;SUB&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L43" class="LineNr"&gt;43 &lt;/span&gt;                m&lt;span class="op_lv0"&gt;.&lt;/span&gt;d&lt;span class="op_lv0"&gt;.&lt;/span&gt;comb &lt;span class="op_lv0"&gt;+=&lt;/span&gt; self&lt;span class="op_lv0"&gt;.&lt;/span&gt;o&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;self&lt;span class="op_lv12"&gt;.&lt;/span&gt;a &lt;span class="op_lv12"&gt;-&lt;/span&gt; self&lt;span class="op_lv12"&gt;.&lt;/span&gt;b&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L44" class="LineNr"&gt;44 &lt;/span&gt;        &lt;span class="Statement"&gt;return&lt;/span&gt; m
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;As you can see, we've created a lot of nMigen &lt;code&gt;Signal&lt;/code&gt; instances to represent
well...the signals that define the interface to our ALU! But what is this
&lt;code&gt;elaborate&lt;/code&gt; method? My understanding is that "elaboration" is the name for the
first step in synthesising the netlist (see above). The idea in the nMigen code
above is that we've created some &lt;em&gt;elaboratable&lt;/em&gt; structure (by inheriting from
&lt;code&gt;nm.Elaboratable&lt;/code&gt;), i.e. something that describes digital logic we want to
synthesise. The &lt;code&gt;elaborate&lt;/code&gt; method describes that digital logic. It has to
return an nMigen &lt;code&gt;Module&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let's have a closer look at the contents of the &lt;code&gt;elaborate&lt;/code&gt; method. The
&lt;code&gt;Switch&lt;/code&gt; will create some kind of decision logic in the synthesised design.
But what is &lt;code&gt;m.d.comb&lt;/code&gt;? nMigen has the concept of synchronous (&lt;code&gt;m.d.sync&lt;/code&gt;)
and combinatorial&lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;4&lt;/a&gt;&lt;/sup&gt; (&lt;code&gt;m.d.comb&lt;/code&gt;) control domains. From the nMigen
&lt;a href="https://nmigen.info/nmigen/latest/lang.html#lang-domains"&gt;docs&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A control domain is a named group of signals that change their value in
identical conditions.&lt;/p&gt;
&lt;p&gt;All designs have a single predefined &lt;em&gt;combinatorial domain&lt;/em&gt;, containing all
signals that change immediately when any value used to compute them changes.
The name comb is reserved for the combinatorial domain.&lt;/p&gt;
&lt;p&gt;A design can also have any amount of user-defined &lt;em&gt;synchronous domains&lt;/em&gt;, also
called clock domains, containing signals that change when a specific edge
occurs on the domain’s clock signal or, for domains with asynchronous reset,
on the domain’s reset signal. Most modules only use a single synchronous
domain[...]&lt;/p&gt;
&lt;p&gt;The behavior of assignments differs for signals in combinatorial and
synchronous domains. Collectively, signals in synchronous domains contain the
state of a design, whereas signals in the combinatorial domain cannot form
feedback loops or hold state.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let's think about a shift register as an example piece of logic that we wish to
design. Let's say our shift register has 8 bits, and every clock cycle the bit
values are shifted one bit along (with the left-most value coming from an input
signal). This is necessarily synchronous: you couldn't create this
functionality by simply wiring the bits together, which in nMigen is what
assigning them in the combinatorial domain would represent.&lt;/p&gt;
&lt;p&gt;In the next installment of this blog series, I'll have more detail on my CPU
design. As it stands at the moment, I'm trying to retire one instruction per
cycle with no pipelining &amp;ndash; this is unusual, but my hope was that it would
make various aspects of the CPU simpler. A consequence of this is that much of
my logic is combinatorial, rather than synchronous, as I have very little state
to maintain between clock cycles. At the moment, something is wrong with my
register file design, and there's a chance I'll have to reassess my "no
pipelining" idea in order to fix it.&lt;/p&gt;
&lt;h2&gt;Writing tests&lt;/h2&gt;
&lt;p&gt;I like using &lt;code&gt;pytest&lt;/code&gt; for Python tests, but you can of course use whatever
framework appeals to you. Here are my tests for the ALU code above:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;ALU tests&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; nmigen&lt;span class="op_lv0"&gt;.&lt;/span&gt;sim
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; pytest
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;&lt;span class="PreProc"&gt;from&lt;/span&gt; riscy_boi &lt;span class="PreProc"&gt;import&lt;/span&gt; alu
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;&lt;span class="op_lv0"&gt;@&lt;/span&gt;pytest&lt;span class="op_lv0"&gt;.&lt;/span&gt;mark&lt;span class="op_lv0"&gt;.&lt;/span&gt;parametrize&lt;span class="lv12c"&gt;(&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;        &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;op, a, b, o&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="lv11c"&gt;[&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;ADD&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;2&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;ADD&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;2&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;3&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;ADD&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;2&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;3&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;ADD&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;258&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;203&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;461&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;ADD&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;5&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;5&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;ADD&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;5&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;5&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;ADD&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;2&lt;/span&gt;&lt;span class="op_lv10"&gt;**&lt;/span&gt;&lt;span class="Number"&gt;32&lt;/span&gt; &lt;span class="op_lv10"&gt;-&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;SUB&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;SUB&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;4942&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;4942&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;,&lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;            &lt;span class="lv10c"&gt;(&lt;/span&gt;alu&lt;span class="op_lv10"&gt;.&lt;/span&gt;ALUOp&lt;span class="op_lv10"&gt;.&lt;/span&gt;SUB&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;2&lt;/span&gt;&lt;span class="op_lv10"&gt;,&lt;/span&gt; &lt;span class="Number"&gt;2&lt;/span&gt;&lt;span class="op_lv10"&gt;**&lt;/span&gt;&lt;span class="Number"&gt;32&lt;/span&gt; &lt;span class="op_lv10"&gt;-&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="lv11c"&gt;]&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;test_alu&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;comb_sim&lt;span class="op_lv12"&gt;,&lt;/span&gt; op&lt;span class="op_lv12"&gt;,&lt;/span&gt; a&lt;span class="op_lv12"&gt;,&lt;/span&gt; b&lt;span class="op_lv12"&gt;,&lt;/span&gt; o&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;    alu_inst &lt;span class="op_lv0"&gt;=&lt;/span&gt; alu&lt;span class="op_lv0"&gt;.&lt;/span&gt;ALU&lt;span class="lv12c"&gt;(&lt;/span&gt;&lt;span class="Number"&gt;32&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;    &lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;testbench&lt;/span&gt;&lt;span class="lv12c"&gt;()&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;        &lt;span class="Statement"&gt;yield&lt;/span&gt; alu_inst&lt;span class="op_lv0"&gt;.&lt;/span&gt;op&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;op&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;        &lt;span class="Statement"&gt;yield&lt;/span&gt; alu_inst&lt;span class="op_lv0"&gt;.&lt;/span&gt;a&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;a&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L26" class="LineNr"&gt;26 &lt;/span&gt;        &lt;span class="Statement"&gt;yield&lt;/span&gt; alu_inst&lt;span class="op_lv0"&gt;.&lt;/span&gt;b&lt;span class="op_lv0"&gt;.&lt;/span&gt;eq&lt;span class="lv12c"&gt;(&lt;/span&gt;b&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L27" class="LineNr"&gt;27 &lt;/span&gt;        &lt;span class="Statement"&gt;yield&lt;/span&gt; nmigen&lt;span class="op_lv0"&gt;.&lt;/span&gt;sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;Settle&lt;span class="lv12c"&gt;()&lt;/span&gt;
&lt;span id="L28" class="LineNr"&gt;28 &lt;/span&gt;        &lt;span class="Statement"&gt;assert&lt;/span&gt; &lt;span class="lv12c"&gt;(&lt;/span&gt;&lt;span class="Statement"&gt;yield&lt;/span&gt; alu_inst&lt;span class="op_lv12"&gt;.&lt;/span&gt;o&lt;span class="lv12c"&gt;)&lt;/span&gt; &lt;span class="op_lv0"&gt;==&lt;/span&gt; o
&lt;span id="L29" class="LineNr"&gt;29 &lt;/span&gt;
&lt;span id="L30" class="LineNr"&gt;30 &lt;/span&gt;    comb_sim&lt;span class="lv12c"&gt;(&lt;/span&gt;alu_inst&lt;span class="op_lv12"&gt;,&lt;/span&gt; testbench&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;and my &lt;code&gt;conftest.py&lt;/code&gt;:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;Test configuration&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; os
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; shutil
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; nmigen&lt;span class="op_lv0"&gt;.&lt;/span&gt;sim
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; pytest
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;VCD_TOP_DIR &lt;span class="op_lv0"&gt;=&lt;/span&gt; os&lt;span class="op_lv0"&gt;.&lt;/span&gt;path&lt;span class="op_lv0"&gt;.&lt;/span&gt;join&lt;span class="lv12c"&gt;(&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;        os&lt;span class="op_lv12"&gt;.&lt;/span&gt;path&lt;span class="op_lv12"&gt;.&lt;/span&gt;dirname&lt;span class="lv11c"&gt;(&lt;/span&gt;os&lt;span class="op_lv11"&gt;.&lt;/span&gt;path&lt;span class="op_lv11"&gt;.&lt;/span&gt;realpath&lt;span class="lv10c"&gt;(&lt;/span&gt;__file__&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="lv11c"&gt;)&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;        &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;tests&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;        &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;vcd&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;vcd_path&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;node&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;    directory &lt;span class="op_lv0"&gt;=&lt;/span&gt; os&lt;span class="op_lv0"&gt;.&lt;/span&gt;path&lt;span class="op_lv0"&gt;.&lt;/span&gt;join&lt;span class="lv12c"&gt;(&lt;/span&gt;VCD_TOP_DIR&lt;span class="op_lv12"&gt;,&lt;/span&gt; node&lt;span class="op_lv12"&gt;.&lt;/span&gt;fspath&lt;span class="op_lv12"&gt;.&lt;/span&gt;basename&lt;span class="op_lv12"&gt;.&lt;/span&gt;split&lt;span class="lv11c"&gt;(&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;.&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="lv11c"&gt;)[&lt;/span&gt;&lt;span class="Number"&gt;0&lt;/span&gt;&lt;span class="lv11c"&gt;]&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;    os&lt;span class="op_lv0"&gt;.&lt;/span&gt;makedirs&lt;span class="lv12c"&gt;(&lt;/span&gt;directory&lt;span class="op_lv12"&gt;,&lt;/span&gt; exist_ok&lt;span class="op_lv12"&gt;=&lt;/span&gt;&lt;span class="Function"&gt;True&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; os&lt;span class="op_lv0"&gt;.&lt;/span&gt;path&lt;span class="op_lv0"&gt;.&lt;/span&gt;join&lt;span class="lv12c"&gt;(&lt;/span&gt;directory&lt;span class="op_lv12"&gt;,&lt;/span&gt; node&lt;span class="op_lv12"&gt;.&lt;/span&gt;name &lt;span class="op_lv12"&gt;+&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;.vcd&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;&lt;span class="op_lv0"&gt;@&lt;/span&gt;pytest&lt;span class="op_lv0"&gt;.&lt;/span&gt;fixture&lt;span class="lv12c"&gt;(&lt;/span&gt;scope&lt;span class="op_lv12"&gt;=&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;session&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; autouse&lt;span class="op_lv12"&gt;=&lt;/span&gt;&lt;span class="Function"&gt;True&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;clear_vcd_directory&lt;/span&gt;&lt;span class="lv12c"&gt;()&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;    shutil&lt;span class="op_lv0"&gt;.&lt;/span&gt;rmtree&lt;span class="lv12c"&gt;(&lt;/span&gt;VCD_TOP_DIR&lt;span class="op_lv12"&gt;,&lt;/span&gt; ignore_errors&lt;span class="op_lv12"&gt;=&lt;/span&gt;&lt;span class="Function"&gt;True&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;
&lt;span id="L26" class="LineNr"&gt;26 &lt;/span&gt;&lt;span class="op_lv0"&gt;@&lt;/span&gt;pytest&lt;span class="op_lv0"&gt;.&lt;/span&gt;fixture
&lt;span id="L27" class="LineNr"&gt;27 &lt;/span&gt;&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;comb_sim&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;request&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L28" class="LineNr"&gt;28 &lt;/span&gt;
&lt;span id="L29" class="LineNr"&gt;29 &lt;/span&gt;    &lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;run&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;fragment&lt;span class="op_lv12"&gt;,&lt;/span&gt; process&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L30" class="LineNr"&gt;30 &lt;/span&gt;        sim &lt;span class="op_lv0"&gt;=&lt;/span&gt; nmigen&lt;span class="op_lv0"&gt;.&lt;/span&gt;sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;Simulator&lt;span class="lv12c"&gt;(&lt;/span&gt;fragment&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L31" class="LineNr"&gt;31 &lt;/span&gt;        sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;add_process&lt;span class="lv12c"&gt;(&lt;/span&gt;process&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L32" class="LineNr"&gt;32 &lt;/span&gt;        &lt;span class="Statement"&gt;with&lt;/span&gt; sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;write_vcd&lt;span class="lv12c"&gt;(&lt;/span&gt;vcd_path&lt;span class="lv11c"&gt;(&lt;/span&gt;request&lt;span class="op_lv11"&gt;.&lt;/span&gt;node&lt;span class="lv11c"&gt;)&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L33" class="LineNr"&gt;33 &lt;/span&gt;            sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;run_until&lt;span class="lv12c"&gt;(&lt;/span&gt;&lt;span class="Number"&gt;100e-6&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L34" class="LineNr"&gt;34 &lt;/span&gt;
&lt;span id="L35" class="LineNr"&gt;35 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; run
&lt;span id="L36" class="LineNr"&gt;36 &lt;/span&gt;
&lt;span id="L37" class="LineNr"&gt;37 &lt;/span&gt;
&lt;span id="L38" class="LineNr"&gt;38 &lt;/span&gt;&lt;span class="op_lv0"&gt;@&lt;/span&gt;pytest&lt;span class="op_lv0"&gt;.&lt;/span&gt;fixture
&lt;span id="L39" class="LineNr"&gt;39 &lt;/span&gt;&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;sync_sim&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;request&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L40" class="LineNr"&gt;40 &lt;/span&gt;
&lt;span id="L41" class="LineNr"&gt;41 &lt;/span&gt;    &lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;run&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;fragment&lt;span class="op_lv12"&gt;,&lt;/span&gt; process&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L42" class="LineNr"&gt;42 &lt;/span&gt;        sim &lt;span class="op_lv0"&gt;=&lt;/span&gt; nmigen&lt;span class="op_lv0"&gt;.&lt;/span&gt;sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;Simulator&lt;span class="lv12c"&gt;(&lt;/span&gt;fragment&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L43" class="LineNr"&gt;43 &lt;/span&gt;        sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;add_sync_process&lt;span class="lv12c"&gt;(&lt;/span&gt;process&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L44" class="LineNr"&gt;44 &lt;/span&gt;        sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;add_clock&lt;span class="lv12c"&gt;(&lt;/span&gt;&lt;span class="Number"&gt;1&lt;/span&gt; &lt;span class="op_lv12"&gt;/&lt;/span&gt; &lt;span class="Number"&gt;10e6&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L45" class="LineNr"&gt;45 &lt;/span&gt;        &lt;span class="Statement"&gt;with&lt;/span&gt; sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;write_vcd&lt;span class="lv12c"&gt;(&lt;/span&gt;vcd_path&lt;span class="lv11c"&gt;(&lt;/span&gt;request&lt;span class="op_lv11"&gt;.&lt;/span&gt;node&lt;span class="lv11c"&gt;)&lt;/span&gt;&lt;span class="lv12c"&gt;)&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L46" class="LineNr"&gt;46 &lt;/span&gt;            sim&lt;span class="op_lv0"&gt;.&lt;/span&gt;run&lt;span class="lv12c"&gt;()&lt;/span&gt;
&lt;span id="L47" class="LineNr"&gt;47 &lt;/span&gt;
&lt;span id="L48" class="LineNr"&gt;48 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; run
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Every test generates a &lt;code&gt;vcd&lt;/code&gt; file for me to view in a wave viewer, like
GTKWave, for debugging purposes. You'll notice that the combinatorial
simulation fixture runs for an arbitrary small time period, whereas the
synchronous simulation feature runs for a defined number of clock cycles.&lt;/p&gt;
&lt;p&gt;Yielding a signal in the test function requests its current value from the
simulator. For combinatorial logic, we yield &lt;code&gt;nmigen.sim.Settle()&lt;/code&gt; to ask the
simulation to complete.&lt;/p&gt;
&lt;p&gt;For synchronous logic, you can also yield without an argument to start a new
clock cycle.&lt;/p&gt;
&lt;h2&gt;Designing a CPU&lt;/h2&gt;
&lt;p&gt;Once I'd gotten familiar with nMigen, I started trying to draw a block diagram
for my CPU. I will go into much more detail on this on the next installment of
this blog series, but I will briefly say that I started by drawing out the
logic required for one instruction, then drew out the logic for another
instruction, then figured out how to combine them. Here's the first messy
sketch:&lt;/p&gt;
&lt;p&gt;&lt;img alt="sketch" src="/images/block-diagram-sktech.jpg" title="A screenshot of my first CPU design sketch"&gt;&lt;/p&gt;
&lt;p&gt;This block diagram step was extremely valuable in figuring out what the
interfaces of different components needed to be, but I wouldn't have wanted to
do it before playing around in nMigen first and learning a bit about digital
logic design in the process. The jazzed up block diagram currently looks like
this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="block" src="/images/riscyboi.png" title="Block diagram of current CPU design"&gt;&lt;/p&gt;
&lt;p&gt;Stay tuned for the next installment where I actually delve into RISC-V and CPU
design. I expect there to be a third installment of me reworking my design and
getting it working on the entire instruction set (RV32I) that I am implementing
:)&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;"if and only if"&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;If you're a software engineer who has worked on high assurance software,
such as that for a high risk medical device, you might think "formal
verification" refers to any formalised verification process. Here I use formal
verification to refer to mathematically proving correctness, see
&lt;a href="https://en.wikipedia.org/wiki/Formal_verification"&gt;https://en.wikipedia.org/wiki/Formal_verification&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Note that you want the nmigen project under the nmigen organisation on
GitHub. You do not want the one under the m-labs organisation. The situation is
a bit unfortunate and complicated, but just know that the former is only one
under active development. It's possible that the active project might change
name soon &amp;ndash; I'll do my best to update this blog post should that happen.&amp;#160;&lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;also known as combinational&amp;#160;&lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/></entry><entry><title>Emulating an STM32F4 in QEMU to test ARM assembly</title><link href="https://mcla.ug/emulating-stm32-qemu.html" rel="alternate"/><published>2020-04-04T00:00:00+01:00</published><updated>2020-04-04T00:00:00+01:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2020-04-04:/emulating-stm32-qemu.html</id><summary type="html">&lt;p&gt;I recently published a blog post titled &lt;a href="https://mcla.ug/blog/how-to-flash-an-led.html" target="_blank"&gt;How to flash an
LED&lt;/a&gt; about writing ARM assembly
for an STM32. I was running my code on a
&lt;a href="https://1bitsy.org/" target="_blank"&gt;1bitsy&lt;/a&gt;
development board, but I wanted anyone to be able to have a go at writing the
assembly and testing it &amp;ndash; even if they …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently published a blog post titled &lt;a href="https://mcla.ug/blog/how-to-flash-an-led.html" target="_blank"&gt;How to flash an
LED&lt;/a&gt; about writing ARM assembly
for an STM32. I was running my code on a
&lt;a href="https://1bitsy.org/" target="_blank"&gt;1bitsy&lt;/a&gt;
development board, but I wanted anyone to be able to have a go at writing the
assembly and testing it &amp;ndash; even if they didn't have the right hardware.
You can find &lt;a href="https://github.com/lochsh/gpio-toggle-exercise" target="_blank"&gt;the repo on my
Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finding the specific QEMU tools I needed took a while, so I wanted to document
it in this blog post.&lt;/p&gt;
&lt;h2&gt;The quest for a QEMU STM32F4 machine&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.qemu.org/" target="_blank"&gt;QEMU&lt;/a&gt; is a "generic and open source machine emulator
and virtualizer". An example where emulation is useful: if you are writing
software for an embedded target, reliable automated tests can be a challenge.
Emulating your embedded target on your host computer makes allows for easier
testing, and for isolating problems to do with the real hardware from problems
to do with the software.&lt;/p&gt;
&lt;p&gt;The 1bitsy has a STM32F415 microcontroller, so I was looking for emulation for
a development board with a similar MCU. QEMU comes with a set of built-in
machines, and you can write your own machines to emulate the hardware you
desire.&lt;/p&gt;
&lt;p&gt;Unfortunately, none of the built-in machines suited my purposes. There were
multiple Cortex M3 machines, but none of them were STM32s, and there were no
Cortex M4 machines. I wanted to use an STM32F4 so as to avoid confusion for
people going from my assembly blog post to the emulation. I also gave the blog
post as a talk at work, and didn't want my coworkers to be confused by the
inconsistency. Creating my own QEMU machine was not remotely feasible on the
timescales I was working on for my work talk, and I believe it is a lot of
work! So, I searched the internet for an available STM32F4 QEMU machine.&lt;/p&gt;
&lt;h3&gt;Enter GNU MCU Eclipse...maybe&lt;/h3&gt;
&lt;p&gt;During this search, I came across many mentions of &lt;a href="https://gnu-mcu-eclipse.github.io/" target="_blank"&gt;GNU MCU
Eclipse&lt;/a&gt;, a suite of tools for the Eclipse
IDE which included an STM32F4 Discovery board.&lt;/p&gt;
&lt;p&gt;I am a &lt;a href="https://www.vim.org/" target="_blank"&gt;vim&lt;/a&gt; die-hard with no desire to use Eclipse, so I
was hopeful to find a way to be able to extract these tools and easily use
them outside of Eclipse.&lt;/p&gt;
&lt;p&gt;It turns out the fork of QEMU that this toolsuite is using is available
separately as &lt;a href="https://xpack.github.io/qemu-arm/" target="_blank"&gt;xPack QEMU
ARM&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;xPack QEMU ARM has an STM32F4 Discovery machine&lt;/h3&gt;
&lt;p&gt;xPack &lt;a href="https://xpack.github.io/qemu-arm/install/" target="_blank"&gt;recommend&lt;/a&gt; using
&lt;a href="https://www.npmjs.com/package/xpm" target="_blank"&gt;xpm&lt;/a&gt; to install their QEMU ARM fork, but I
found the manual installation instructions worked fine on Ubuntu. This gives
us, among other things, the &lt;code&gt;qemu-system-gnuarmeclipse&lt;/code&gt; binary.&lt;/p&gt;
&lt;h2&gt;Connecting to the emulator via gdb&lt;/h2&gt;
&lt;p&gt;We can run our target executable on the emulator like this, with the &lt;code&gt;gdb&lt;/code&gt;
switch telling QEMU to wait for a connection from gdb before continuing the
program's execution. Here, we tell it listen on TCP port 3333.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;qemu&lt;span class="op_lv0"&gt;-&lt;/span&gt;system&lt;span class="op_lv0"&gt;-&lt;/span&gt;gnuarmeclipse &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;cpu cortex&lt;span class="op_lv0"&gt;-&lt;/span&gt;m4 &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;machine STM32F4&lt;span class="op_lv0"&gt;-&lt;/span&gt;Discovery &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;gdb tcp&lt;span class="op_lv0"&gt;::&lt;/span&gt;&lt;span class="Number"&gt;3333&lt;/span&gt; &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;nographic &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;kernel &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;TARGET&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Then we can connect from gdb:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;gdb&lt;span class="op_lv0"&gt;-&lt;/span&gt;multiarch &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;q &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;TARGET&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;ex &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;target remote :3333&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;h2&gt;Automated testing of ARM assembly on the STM32F4 emulator&lt;/h2&gt;
&lt;p&gt;I put all this together into a bash script so I could test that assembly for
toggling a GPIO pin was doing what it should, by reading register values from
gdb at breakpoints set in the assembly file:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Comment"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;&lt;span class="Statement"&gt;set&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Special"&gt;-euo&lt;/span&gt;&lt;span class="Identifier"&gt; pipefail&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;&lt;span class="Identifier"&gt;TARGET&lt;/span&gt;=&lt;span class="PreProc"&gt;$1&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;qemu&lt;span class="op_lv0"&gt;-&lt;/span&gt;system&lt;span class="op_lv0"&gt;-&lt;/span&gt;gnuarmeclipse &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;cpu cortex&lt;span class="op_lv0"&gt;-&lt;/span&gt;m4 &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;machine STM32F4&lt;span class="op_lv0"&gt;-&lt;/span&gt;Discovery &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;gdb tcp&lt;span class="op_lv0"&gt;::&lt;/span&gt;3333 &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;nographic &lt;span class="Statement"&gt;\&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;    &lt;span class="op_lv0"&gt;-&lt;/span&gt;kernel &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;TARGET&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="op_lv0"&gt;&amp;gt;&lt;/span&gt; &lt;span class="op_lv0"&gt;/&lt;/span&gt;dev&lt;span class="op_lv0"&gt;/&lt;/span&gt;null &lt;span class="op_lv0"&gt;&amp;amp;&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;&lt;span class="Identifier"&gt;QEMU_PID&lt;/span&gt;=&lt;span class="PreProc"&gt;$!&lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;&lt;span class="Statement"&gt;if &lt;/span&gt;&lt;span class="Statement"&gt;[&lt;/span&gt; &lt;span class="Statement"&gt;!&lt;/span&gt; &lt;span class="Statement"&gt;-d&lt;/span&gt; &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;/proc/&lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;QEMU_PID&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;]&lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;&lt;span class="Statement"&gt;then&lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;    &lt;span class="Statement"&gt;echo&lt;/span&gt;&lt;span class="String"&gt; -ne &lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;\033&lt;/span&gt;&lt;span class="String"&gt;[31m Failed to start QEMU&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;    &lt;span class="Statement"&gt;echo&lt;/span&gt;&lt;span class="String"&gt; -e &lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;\033&lt;/span&gt;&lt;span class="String"&gt;[0m&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;    &lt;span class="Statement"&gt;exit&lt;/span&gt; &lt;span class="Number"&gt;1&lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;&lt;span class="Statement"&gt;fi&lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;&lt;span class="Function"&gt;function&lt;/span&gt; &lt;span class="Function"&gt;read_address() {&lt;/span&gt;
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;    &lt;span class="Statement"&gt;local&lt;/span&gt;&lt;span class="Identifier"&gt; ADDRESS=&lt;/span&gt;&lt;span class="PreProc"&gt;$1&lt;/span&gt;
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;    &lt;span class="Identifier"&gt;VALUE&lt;/span&gt;=&lt;span class="PreProc"&gt;$(&lt;/span&gt;&lt;span class="Special"&gt;gdb-multiarch \&lt;/span&gt;
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;&lt;span class="Special"&gt;        &lt;/span&gt;&lt;span class="Special"&gt;-q&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;TARGET&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt; \&lt;/span&gt;
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;&lt;span class="Special"&gt;        &lt;/span&gt;&lt;span class="Special"&gt;-ex&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;target remote :3333&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt; \&lt;/span&gt;
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;&lt;span class="Special"&gt;        &lt;/span&gt;&lt;span class="Special"&gt;-ex&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;x/1xw &lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;ADDRESS&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt; \&lt;/span&gt;
&lt;span id="L26" class="LineNr"&gt;26 &lt;/span&gt;&lt;span class="Special"&gt;        &lt;/span&gt;&lt;span class="Special"&gt;--batch&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Statement"&gt;|&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Statement"&gt;tail&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Number"&gt;-1&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Statement"&gt;|&lt;/span&gt;&lt;span class="Special"&gt; cut &lt;/span&gt;&lt;span class="Special"&gt;-f&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Number"&gt;2&lt;/span&gt;&lt;span class="PreProc"&gt;)&lt;/span&gt;
&lt;span id="L27" class="LineNr"&gt;27 &lt;/span&gt;&lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span id="L28" class="LineNr"&gt;28 &lt;/span&gt;
&lt;span id="L29" class="LineNr"&gt;29 &lt;/span&gt;&lt;span class="Function"&gt;function&lt;/span&gt; &lt;span class="Function"&gt;test_address() {&lt;/span&gt;
&lt;span id="L30" class="LineNr"&gt;30 &lt;/span&gt;    &lt;span class="Statement"&gt;local&lt;/span&gt;&lt;span class="Identifier"&gt; ADDRESS=&lt;/span&gt;&lt;span class="PreProc"&gt;$1&lt;/span&gt;
&lt;span id="L31" class="LineNr"&gt;31 &lt;/span&gt;    &lt;span class="Statement"&gt;local&lt;/span&gt;&lt;span class="Identifier"&gt; REGISTER_NAME=&lt;/span&gt;&lt;span class="PreProc"&gt;$2&lt;/span&gt;
&lt;span id="L32" class="LineNr"&gt;32 &lt;/span&gt;    &lt;span class="Statement"&gt;local&lt;/span&gt;&lt;span class="Identifier"&gt; EX_VALUE=&lt;/span&gt;&lt;span class="PreProc"&gt;$3&lt;/span&gt;
&lt;span id="L33" class="LineNr"&gt;33 &lt;/span&gt;
&lt;span id="L34" class="LineNr"&gt;34 &lt;/span&gt;    read_address &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;ADDRESS&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L35" class="LineNr"&gt;35 &lt;/span&gt;    &lt;span class="Statement"&gt;if &lt;/span&gt;&lt;span class="Statement"&gt;[&lt;/span&gt; &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="PreProc"&gt;$VALUE&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;EX_VALUE&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;]&lt;/span&gt;
&lt;span id="L36" class="LineNr"&gt;36 &lt;/span&gt;    &lt;span class="Statement"&gt;then&lt;/span&gt;
&lt;span id="L37" class="LineNr"&gt;37 &lt;/span&gt;        &lt;span class="Statement"&gt;echo&lt;/span&gt;&lt;span class="String"&gt; -ne &lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;\033&lt;/span&gt;&lt;span class="String"&gt;[32m&lt;/span&gt;&lt;span class="Special"&gt;✓&lt;/span&gt;&lt;span class="String"&gt; &lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;REGISTER_NAME&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="String"&gt; correctly set to &lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;EX_VALUE&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L38" class="LineNr"&gt;38 &lt;/span&gt;    &lt;span class="Statement"&gt;else&lt;/span&gt;
&lt;span id="L39" class="LineNr"&gt;39 &lt;/span&gt;        &lt;span class="Statement"&gt;echo&lt;/span&gt;&lt;span class="String"&gt; -ne &lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;\033&lt;/span&gt;&lt;span class="String"&gt;[31m&lt;/span&gt;&lt;span class="Special"&gt;✘&lt;/span&gt;&lt;span class="String"&gt; &lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;REGISTER_NAME&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="String"&gt; was &lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;VALUE&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="String"&gt;, want &lt;/span&gt;&lt;span class="PreProc"&gt;${&lt;/span&gt;&lt;span class="PreProc"&gt;EX_VALUE&lt;/span&gt;&lt;span class="PreProc"&gt;}&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L40" class="LineNr"&gt;40 &lt;/span&gt;    &lt;span class="Statement"&gt;fi&lt;/span&gt;
&lt;span id="L41" class="LineNr"&gt;41 &lt;/span&gt;
&lt;span id="L42" class="LineNr"&gt;42 &lt;/span&gt;    &lt;span class="Statement"&gt;echo&lt;/span&gt;&lt;span class="String"&gt; -e &lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;\033&lt;/span&gt;&lt;span class="String"&gt;[0m&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L43" class="LineNr"&gt;43 &lt;/span&gt;&lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span id="L44" class="LineNr"&gt;44 &lt;/span&gt;
&lt;span id="L45" class="LineNr"&gt;45 &lt;/span&gt;test_address &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;0x40023830&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;AHB1ENR&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;0x00000001&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L46" class="LineNr"&gt;46 &lt;/span&gt;test_address &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;0x40020000&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;GPIOA_MODER&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;0xa8010000&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L47" class="LineNr"&gt;47 &lt;/span&gt;test_address &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;0x40020014&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;GPIOA_ODR&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt; &lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;0x00000100&lt;/span&gt;&lt;span class="Statement"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L48" class="LineNr"&gt;48 &lt;/span&gt;
&lt;span id="L49" class="LineNr"&gt;49 &lt;/span&gt;&lt;span class="Statement"&gt;kill&lt;/span&gt; &lt;span class="op_lv0"&gt;$&lt;/span&gt;&lt;span class="lv12c"&gt;{&lt;/span&gt;QEMU_PID&lt;span class="lv12c"&gt;}&lt;/span&gt; &lt;span class="op_lv0"&gt;&amp;amp;&amp;gt;&lt;/span&gt; &lt;span class="op_lv0"&gt;/&lt;/span&gt;dev&lt;span class="op_lv0"&gt;/&lt;/span&gt;null
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;The output looks like this for correct assembly, which you can view
&lt;a href="https://github.com/lochsh/gpio-toggle-exercise/blob/master/sneak-peek/working-gpio-toggle.s"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/qemu-output.png" width="400" alt="QEMU script output" class=callout&gt;&lt;/p&gt;
&lt;p&gt;This testing is limited, but I'm pleased with it! I put everything in a
Dockerfile in the Github repo to make life easier for people trying this out.&lt;/p&gt;
&lt;h2&gt;Bonus 1337 screenshot&lt;/h2&gt;
&lt;p&gt;This is a screenshot from when I finally got all this working after a couple
evenings of trials:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/qemu-all-screenshot.png" class=callout&gt;&lt;/p&gt;
&lt;p&gt;Clockwise from left is the assembly, the bash script, a gdb session where I'd
been poking around, and me running the bash script.&lt;/p&gt;
&lt;p&gt;I hope this is post helpful to anyone wanting to emulate an STM32F4 without
having to do it all themselves, and that the tools in my
&lt;a href="https://github.com/lochsh/gpio-toggle-exercise" target="_blank"&gt;GPIO toggling
exercise&lt;/a&gt; are
useful to anyone who wants to play with ARM assembly but doesn't have the
hardware.&lt;/p&gt;</content><category term="misc"/></entry><entry><title>How to flash an LED</title><link href="https://mcla.ug/how-to-flash-an-led.html" rel="alternate"/><published>2020-03-27T00:00:00+00:00</published><updated>2020-03-27T00:00:00+00:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2020-03-27:/how-to-flash-an-led.html</id><summary type="html">&lt;p&gt;Today we are going to be learning how to flash an LED on a microcontroller by
writing ARM assembly.&lt;/p&gt;
&lt;p&gt;If you write software but are  unfamiliar with basic electronics or embedded
software development, there will be explanations of some fundamentals &amp;ndash; I
expect you will not feel left behind :).&lt;/p&gt;
&lt;p&gt;If you'd …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Today we are going to be learning how to flash an LED on a microcontroller by
writing ARM assembly.&lt;/p&gt;
&lt;p&gt;If you write software but are  unfamiliar with basic electronics or embedded
software development, there will be explanations of some fundamentals &amp;ndash; I
expect you will not feel left behind :).&lt;/p&gt;
&lt;p&gt;If you'd like to skip the fundamentals and go straight to the assembly writing,
click &lt;a href="#writingcode"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We'll be using a &lt;a href="https://1bitsy.org/" target="_blank"&gt;1bitsy&lt;/a&gt;, which is an
&lt;a href="https://www.st.com/en/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus.html" target="_blank"&gt;STM32&lt;/a&gt; development
board. We'll be reading the STM32 reference manual to figure out what assembly
to write. If you want to try out the coding yourself, but don't have a 1bitsy
or anything similar, check out &lt;a href="https://github.com/lochsh/gpio-toggle-exercise" target="_blank"&gt;this Github repo&lt;/a&gt;
where you can run the code on an emulator in a Docker container.&lt;/p&gt;
&lt;h1&gt;Some basics&lt;/h1&gt;
&lt;p&gt;Let's get some basics out of the way. How &lt;em&gt;do&lt;/em&gt; you flash an LED?&lt;/p&gt;
&lt;h2&gt;Hardware&lt;/h2&gt;
&lt;p&gt;&lt;img src="/images/led-flash/led.svg" width="100" alt="LED circuit symbol" class=callout&gt;
As you may know, an LED is a "light-emitting diode". LEDs are
increasingly popular in torches, bulbs and various other lighting due to their
ability to be very bright with relatively low power. What we need to know is
that they emit light when current passes through them. So: we need some
current.&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/led-flash/ledcircuit.svg" width="100" alt="LED circuit" class=callout&gt;
This is just a simple electronics circuit with current flowing through the LED.
We have low voltage at the bottom, and higher voltage at the top: that
difference causes current to flow, lighting up our LED. But this is no good for
us &amp;ndash; we want to control the flow of current so that we can flash our LED on
and off.&lt;/p&gt;
&lt;p&gt;In order to control the current in our LED, we can connect it to a GPIO pin on
our microcontroller:
&lt;img src="/images/led-flash/ledcircuitgpio.svg" width="300" alt="LED connected to a GPIO" class=callout&gt;&lt;/p&gt;
&lt;p&gt;GPIO just stands for "general purpose input/output". It's a pin on a
microchip that you can configure at runtime: for example, you can say "I
want this pin to be an output, and I want to turn it on", or "I want this pin
to be an input" and then read data from it.&lt;/p&gt;
&lt;p&gt;A microcontroller is a small computer used for embedded software &amp;ndash; we'll learn
more about the specific microcontroller we're using later. Embedded software is
software that isn't written for a general purpose computer, but instead targets
specific hardware used in some physical device: for example, the software that
runs on an MRI scanner to control its operation, or the software in modern cars
that controls things like the anti-lock braking system.&lt;/p&gt;
&lt;h2&gt;Software&lt;/h2&gt;
&lt;p&gt;If GPIO pins are configurable at runtime, then we need to write
some code that will tell our little computer how to configure the
GPIO. This is how that would usually look:&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/led-flash/ledsoftwarecompile.svg" width="100%" alt="embedded software development process" class=callout&gt;&lt;/p&gt;
&lt;p&gt;Usually, you'd expect that code to be written in C. You need a language that
allows you control over memory the way that C does: when you have small limited
memory, as is generally the case on small embedded computers,
it's important to be able to understand how much memory is being used by
your program. Languages that rely on dynamic allocation and garbage collection
are a bad fit, partly for this reason.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mcla.ug/blog/rust-a-future-for-real-time-and-safety-critical-software.html" target="_blank"&gt;Rust&lt;/a&gt; and C++ are also used for embedded work. The C++ you'd write for embedded
would be quite different from what you might write for a desktop application
&amp;ndash; you likely wouldn't use any of the STL containers as they all rely on
dynamic memory allocation.  Eliminating dynamic memory allocation is safer: the
risk of memory allocation failing is much higher when there isn't much memory
to begin with.  And a failure could be much more catastrophic: many embedded
systems are designed to run autonomously, without any human there to restart
them. Many control safety-critical physical systems.&lt;/p&gt;
&lt;p&gt;Dynamic allocation is generally not needed anyway:  a desktop application might
have to dynamically allocate resources to accommodate a user opening an unknown
number of tabs in a GUI; an embedded application will know at compile time how
many motors it has to control, or how many sensors it will read from. This
allows a lot of memory to be allocated statically.&lt;/p&gt;
&lt;p&gt;So, for the sake of example let's say that you would write your code to flash
an LED in C.  You'd probably use a hardware abstraction library (aka a HAL) to
abstract over memory addresses and such. This makes the code more portable as
well as more readable.&lt;/p&gt;
&lt;p&gt;But today, we're going to do stuff a little differently from how you might
normally: we'll be writing all our code in assembly.&lt;/p&gt;
&lt;h2&gt;What is assembly?&lt;/h2&gt;
&lt;p&gt;When you compile a C program, say, you compile it to machine code. Machine code
is the lowest level of software &amp;ndash; it's the binary code that the CPU
executes.  This machine code consists of &lt;em&gt;instructions&lt;/em&gt;. For example, you might
have one instruction that says "copy value 42 into register 0", and that is our
smallest unit of executable code.&lt;/p&gt;
&lt;p&gt;Assembly is the next level of software up &amp;ndash; it's a lot like writing human
readable machine code, where you write out each instruction in text form.  This
is very different to writing a C program which is much further abstracted,
which means compiling C to machine code is a lot more complicated. When we
write assembly today, that's exactly what our CPU is going to be executing:
there's a very close mapping to the actual machine code.&lt;/p&gt;
&lt;h2&gt;Why write our code in assembly?&lt;/h2&gt;
&lt;p&gt;The usual reasons: for fun and learning! Writing code in assembly means really
getting to know your target hardware. Plus, we'll know exactly what code is
running on our processor.&lt;/p&gt;
&lt;p&gt;Although this isn't something you might usually do, understanding assembly code
is a big part of many developers' jobs: reading the assembly is often the only
way to debug optimised code, and it's crucial to reverse engineering and
exploit development. It's also key to compiler development, and used for making
specific optimisations to embedded code. It's often the only way to access
specialised CPU features, and to run special instructions like DSP
instructions.&lt;/p&gt;
&lt;h1&gt;Getting to know our hardware&lt;/h1&gt;
&lt;p&gt;Doing embedded development means really getting to know your target hardware.
So, what hardware are we using?&lt;/p&gt;
&lt;p&gt;&lt;img alt="hardware" src="/images/led-flash/hardware.png" title="list of hardware and documentation"&gt;&lt;/p&gt;
&lt;p&gt;We have an ARM development board called a 1bitsy. It has an STM32F4 on it,
which is our microcontroller unit, or MCU. This microcontroller is basically
the CPU plus about a megabyte of flash and 200 kilobytes of RAM, and what
are called peripherals: some of these are for communicating via various
protocols, and some are for general purposes usage, like the GPIOs we talked
about earlier.  The MCU has everything you need to make the CPU actually be
a useful computer.  Our STM32 contains a Cortex M4 CPU &amp;ndash; the picture
above is of the die of the STM32, it's basically what's inside the black
plastic on the outside of the chip.  The CPU is on the top right of the die,
with RAM top left, flash bottom left, and peripherals bottom right.&lt;/p&gt;
&lt;p&gt;I've included lists of the documentation associated with these. Today we're
exclusively going to be looking at the schematic for the board and the
reference manual for the STM32.&lt;/p&gt;
&lt;p&gt;To program the 1bitsy, we will also need a prorgrammer board like the
&lt;a href="https://github.com/blacksphere/blackmagic/wiki" target="_blank"&gt;Black Magic probe&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;A brief introduction to assembly&lt;/h1&gt;
&lt;h2&gt;What does assembly look like?&lt;/h2&gt;
&lt;p&gt;Before we get onto writing some code, what does ARM assembly look like?&lt;/p&gt;
&lt;p&gt;Here is an example instruction: &lt;code&gt;mov r0, #5&lt;/code&gt;. This means move the literal value
5 into register 0. But what's a register? A register is the last key concept
we're going to need to know before we write any assembly.&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/led-flash/registers.svg" width="250" alt="registers of Cortex M4" class=callout&gt;&lt;/p&gt;
&lt;p&gt;Our ARM processor has a small number of very fast, very small storage
locations, and they're called registers. These are directly accessed by the
CPU, and they aren't accessible via main memory. Some are used for general
purpose storage, others have specific purposes, like the program counter
register (PC). The CPU is hardwired to execute whatever instruction is at the
memory location stored in the PC. The stack pointer is used to keep track of
the call stack.&lt;/p&gt;
&lt;p&gt;On a separate memory bus, our STM32 also has about a thousand configuration and
status registers &amp;ndash; also often called memory-mapped IO. These are basically
pre-defined structs that live somewhere in memory, and you read &amp;amp; write to them
in order to configure the hardware. In our case, we'll be writing to these to
configure a GPIO, which will be connected to our LED.&lt;/p&gt;
&lt;h2&gt;RISC vs CISC&lt;/h2&gt;
&lt;p&gt;I think it's important context to note that the assembly we'll be writing today
is a little different than what you would likely write for your PC. Broadly,
you can divide computer architectures into complex instruction set computers
(CISC) and reduced instruction set computers (RISC).  CISC is what Intel
chips use, and it is optimised to perform actions in as few instructions as
possible &amp;ndash; as a consequence each instruction itself can be very complex.
RISC, on the other hand, prioritises having simple instructions, and you'll
be glad to know that's what we'll be writing today.&lt;/p&gt;
&lt;p&gt;I couldn't resist including a screenshot from Hackers, my favourite movie,
which is from 1995, a much more hopeful time in software.&lt;/p&gt;
&lt;p&gt;&lt;img alt="risc" src="/images/led-flash/risc.png" title="screengrab from Hackers the movie"&gt;&lt;/p&gt;
&lt;p&gt;Here the hacker Acid Burn is saying that RISC architecture is going to change
everything &amp;ndash; and in many ways she's right! I don't know of any mobile phone,
Apple or Android, that doesn't use an ARM core, and mobile phones are
everywhere. Sadly, most laptops and desktops use Intel CISC processors. This
makes no difference to my life at all, but I like to pretend it matters to me
so I can feel like I'm as cool as Acid Burn.&lt;/p&gt;
&lt;h1 id="writingcode"&gt;Let's write some code!&lt;/h1&gt;
&lt;p&gt;At last...it is time to get down to business. First we need to briefly
look at the &lt;a href="https://github.com/1Bitsy/1bitsy-hardware/blob/51de093b188c909c3b7af41ad1a1134d68a42f0e/1bitsy/v1.0d/1bitsy_schematic.pdf" target="_blank"&gt;schematic&lt;/a&gt;
for the 1bitsy, our development board. The schematic tells us what is on the
board, and how it is connected. We're interested in how the status LED is
connected.&lt;/p&gt;
&lt;p&gt;Because the 1bitsy is quite simple, there is only one page to the schematic.
If we look at the top of the schematic, centre-right, we can see that there's a
status LED connected to GPIO port A, pin 8, which we'll call PA8 for short.&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/led-flash/ledschematic.png" width="250" alt="LED in 1bitsy schematic" class=callout&gt;&lt;/p&gt;
&lt;p&gt;There are three things we're going to need to do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Turn on the GPIOA clock&lt;/li&gt;
&lt;li&gt;Set GPIOA8 to an output&lt;/li&gt;
&lt;li&gt;Toggle GPIOA8&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Turning on the clock&lt;/h2&gt;
&lt;p&gt;Before we can do anything with this GPIO pin, we need to set up its clock.
Inside our chip, and inside the CPUs in our work laptops, there's a oscillator
providing a clock signal that is used to synchronise different parts of the
complicated integrated circuit that is our computer.&lt;/p&gt;
&lt;p&gt;If we are going to use our GPIO pin, it needs to have its clock enabled,
otherwise it is effectively off, and won't respond to any reads or writes.
It defaults to being off because the peripheral consumes power when it's on.&lt;/p&gt;
&lt;p&gt;To find out how to setup the GPIOA clock, we need to look at the STM32F415
&lt;a href="https://tinyurl.com/f4-ref-man" target="_blank"&gt;reference manual&lt;/a&gt;, or ref man for short.
We want to look at the memory map, to see what the start address is for the
Reset and Clock Control (RCC) registers.&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/led-flash/memory-map-rcc.png" width="100%" alt="STM32 memory map" class=callout&gt;&lt;/p&gt;
&lt;p&gt;We're going to need a bit more information in order to set the clock, but this
memory address is something we'll need in our code, so let's make a note of it
(0x40023800).&lt;/p&gt;
&lt;p&gt;Let's go to the RCC register map next &amp;ndash; this is how we're going to find
exactly which RCC register we need to write to in order to turn on the GPIOA
clock.&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/led-flash/rcc-register-map.png" width="100%" alt="RCC register map" class=callout&gt;&lt;/p&gt;
&lt;p&gt;The first column in this table shows the address offset from the base address
we noted earlier. The numbers from 31 to 0 show the bits of the 32-bit
registers.&lt;/p&gt;
&lt;p&gt;If we look closely, we can see the field GPIOA_ENR for enabling GPIOA's clock
&amp;ndash; so, we want to set bit 0 in the AHB1ENR register. I realise that might
seem very obscure; I think there are two things to note: firstly, there's
actually a lot of additional documentation about this elsewhere in the ref man,
showing the different memory buses and the clock tree. It would be too dense to
show in this blog post.&lt;/p&gt;
&lt;p&gt;Secondly, when you create a software API, a huge priority is making something
that is useable and clear to developers (I should hope it is, anyway). When
designing hardware, there are physical constraints, and the design &lt;em&gt;has&lt;/em&gt;
to be cheap and simple to mass manufacture. Consequently, clarity for us chumps
cannot be a priority, and instead of a method call with helpfully named
arguments, we have dense manuals like this...&lt;/p&gt;
&lt;p&gt;Reading this sort of documentation does get easier the more you get to know
your architecture, and the more experience you have reading similar manuals
&amp;ndash; as with anything :)&lt;/p&gt;
&lt;h3&gt;Actually writing code for real&lt;/h3&gt;
&lt;p&gt;Now: we're finally going to write some actual code. I am sorry I said "let's
write some code" further up. We couldn't do it until we had this information
from the ref man!&lt;/p&gt;
&lt;p&gt;Let's copy that RCC base address into register 0. Our registers are all 32 bits
wide, but we can only copy 16 bits at a time, otherwise we'd have no room for
the rest of our instruction. So, we copy 0x00003800 into the register using the
&lt;code&gt;mov&lt;/code&gt; instruction, and then copy 0x4002 into the top half, hence the &lt;code&gt;t&lt;/code&gt; in
&lt;code&gt;movt&lt;/code&gt; below.&lt;/p&gt;
&lt;p&gt;Then, we want to set the 0th bit in the AHB1ENR register. First, let's copy
0x01 into r1. Then, let's store the contents of r1 in the memory address
contained in r0, offset by 0x30 using the &lt;code&gt;str&lt;/code&gt; instruction.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Store&lt;/span&gt; &lt;span class="Function"&gt;RCC&lt;/span&gt; &lt;span class="Function"&gt;base&lt;/span&gt; &lt;span class="Function"&gt;address&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x3800&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x4002&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Turn&lt;/span&gt; &lt;span class="Function"&gt;on&lt;/span&gt; &lt;span class="Function"&gt;GPIOA&lt;/span&gt; &lt;span class="Function"&gt;clock&lt;/span&gt; &lt;span class="Function"&gt;by&lt;/span&gt; &lt;span class="Function"&gt;setting&lt;/span&gt; &lt;span class="Function"&gt;bit&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;AHB1ENR&lt;/span&gt; &lt;span class="Function"&gt;register&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x01&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt;7 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x30&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;With these runes, we can enable the clock!&lt;/p&gt;
&lt;p&gt;All the &lt;code&gt;mov&lt;/code&gt; instructions are about moving data into registers. The &lt;code&gt;str&lt;/code&gt;
instruction moves data from registers and into memory.&lt;/p&gt;
&lt;p&gt;You can read more detail about these instructions in the &lt;a href="http://infocenter.arm.com/help/topic/com.arm.doc.dui0553b/DUI0553.pdf" target="_blank"&gt;User Guide&lt;/a&gt; for our CPU.&lt;/p&gt;
&lt;h2&gt;Setting GPIOA8 to an output&lt;/h2&gt;
&lt;p&gt;Next on our list is configuring GPIOA8 to be an output. As before, we can look
up the base address of GPIOA registers in the ref man. It's 0x40020000. Then,
we can have a read of the GPIO registers to find out which one we need to write
to.&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/led-flash/gpioen.png" width="100%" alt="GPIO enable register" class=callout&gt;&lt;/p&gt;
&lt;p&gt;It looks like we want GPIOA_MODER, and you can see above that the reset value
is 0xA8000000 for GPIOA. I understand this is because some of the GPIOA pins
are used for the debug interface of the STM32, otherwise the reset value would
be all zeroes. We want to change the two-bit field MODER8 to be 01, so we want
to set the register value to 0xA8010000.  There is no offset this time as the
mode register is the first GPIO register.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Store&lt;/span&gt; &lt;span class="Function"&gt;start&lt;/span&gt; &lt;span class="Function"&gt;address&lt;/span&gt; &lt;span class="Function"&gt;of&lt;/span&gt; &lt;span class="Function"&gt;GPIOA&lt;/span&gt; &lt;span class="Function"&gt;registers&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0000&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x4002&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Use&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_MODER&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;make&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt; &lt;span class="Function"&gt;an&lt;/span&gt; &lt;span class="Function"&gt;output&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0000&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt;7 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0xA801&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt;8 &lt;/span&gt;    &lt;span class="Keyword"&gt;str &lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;h2&gt;Toggling the GPIO&lt;/h2&gt;
&lt;p&gt;&lt;img src="/images/led-flash/gpiooutdata.png" width="100%" alt="GPIO output data register" class=callout&gt;
If we look at the GPIO documentation, it tells us that there is an output data
register, but access to it isn't atomic. That's not a big problem for us here
as we don't have any concurrency, but maybe we will later on! We can use the
bit-set-reset register for atomic access instead. This also allows us to set
individual bits in the output data register, instead of overwriting any values
on other GPIO pins.&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/led-flash/bsrr.png" width="100%" alt="GPIO output data register" class=callout&gt;&lt;/p&gt;
&lt;p&gt;The direction our LED has been wired up means it's active low, so it will turn
on when the GPIO output is cleared, and off when it is set.&lt;/p&gt;
&lt;p&gt;So, to turn on our LED we want to set the BR8 field, and to turn it off, we
want to set the BS8 field.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Set&lt;/span&gt; &lt;span class="Function"&gt;BR8&lt;/span&gt; &lt;span class="Function"&gt;field&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_BSRR&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;clear&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0000&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0100&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x18&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Set&lt;/span&gt; &lt;span class="Function"&gt;BS8&lt;/span&gt; &lt;span class="Function"&gt;field&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_BSRR&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;set&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt;7 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0100&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt;8 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x18&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;h3&gt;Looping&lt;/h3&gt;
&lt;p&gt;The last code snippet will just turn the LED off and on once. To create an
infinite loop instead, we simply create a label (let's call it &lt;code&gt;.loop&lt;/code&gt;) and
then use the branch instruction to go back to that label!&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="op_lv0"&gt;.&lt;/span&gt;loop&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Set&lt;/span&gt; &lt;span class="Function"&gt;BR8&lt;/span&gt; &lt;span class="Function"&gt;field&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_BSRR&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;clear&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0000&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0100&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x18&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Set&lt;/span&gt; &lt;span class="Function"&gt;BS8&lt;/span&gt; &lt;span class="Function"&gt;field&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_BSRR&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;set&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0100&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x18&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;    &lt;span class="Keyword"&gt;b&lt;/span&gt; &lt;span class="op_lv0"&gt;.&lt;/span&gt;loop
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;h3&gt;Adding a delay&lt;/h3&gt;
&lt;p&gt;Now for something that is hopefully a lot more interesting than just shoving
values into memory addresses. We want to do this in a loop, with a delay
between turning the LED off an on!&lt;/p&gt;
&lt;p&gt;There are a few ways you could do this delay. If precise timing was important,
the timer peripherals of the STM32 can be used. We could also just add a lot of
&lt;code&gt;nop&lt;/code&gt; (no operation) over and over again -- that doesn't feel very
sophisticated, and would give us a really large binary!&lt;/p&gt;
&lt;p&gt;We're going to do this by putting a big number in a register and decrementing
it until it hits zero. So, we're creating another loop, but this time with an
exit condition.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="op_lv0"&gt;.&lt;/span&gt;loop&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Set&lt;/span&gt; &lt;span class="Function"&gt;BR8&lt;/span&gt; &lt;span class="Function"&gt;field&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_BSRR&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;clear&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0000&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0100&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x18&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Delay&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x3500&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x000c&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;&lt;span class="op_lv0"&gt;.&lt;/span&gt;L&lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;    &lt;span class="Keyword"&gt;subs&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0001&lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;    &lt;span class="Keyword"&gt;bne&lt;/span&gt; &lt;span class="op_lv0"&gt;.&lt;/span&gt;L&lt;span class="Constant"&gt;1&lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Set&lt;/span&gt; &lt;span class="Function"&gt;BS8&lt;/span&gt; &lt;span class="Function"&gt;field&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_BSRR&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;set&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0100&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x18&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Delay&lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x3500&lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x000c&lt;/span&gt;
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;&lt;span class="op_lv0"&gt;.&lt;/span&gt;L&lt;span class="Constant"&gt;2&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;    &lt;span class="Keyword"&gt;subs&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0001&lt;/span&gt;
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;    &lt;span class="Keyword"&gt;bne&lt;/span&gt; &lt;span class="op_lv0"&gt;.&lt;/span&gt;L&lt;span class="Constant"&gt;2&lt;/span&gt;
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;    &lt;span class="Keyword"&gt;b&lt;/span&gt; &lt;span class="op_lv0"&gt;.&lt;/span&gt;loop
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;The &lt;code&gt;subs&lt;/code&gt; instruction here is subtracting, and the &lt;code&gt;s&lt;/code&gt; suffix means that a
flag will be set in the Program Status Register if the result of the operation
is zero. The &lt;code&gt;bne&lt;/code&gt; instruction means "branch if not equal (to zero)", so we'll
jump back to the start of our delay loop if that zero flag isn't set.&lt;/p&gt;
&lt;h2&gt;Putting the pieces together&lt;/h2&gt;
&lt;p&gt;We now have everything we need to flash our LED &amp;ndash; almost.&lt;/p&gt;
&lt;p&gt;There's some boilerplate that needs added to our assembly file. We need to give
our a name to the entry point, let's call it &lt;code&gt;main&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;There are two instruction encodings for ARM: ARM and Thumb. The encoding
defines how the assembly is translated to machine code. It used to be that you
needed different syntax for each of these, until ARM brought out their unified
assembly language. Line 1 below is telling the assembler (the tool that turns
the assembly into machine code) which syntax we are using.&lt;/p&gt;
&lt;p&gt;Then, line 3 is telling the assembler that we are using the Thumb encoding for
&lt;code&gt;main&lt;/code&gt;, which is the only encoding our target (the STM32F4) supports. Then line
4 is exposing the symbol &lt;code&gt;main&lt;/code&gt; to the linker.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="PreProc"&gt;.syntax&lt;/span&gt; &lt;span class="Function"&gt;unified&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&lt;span class="PreProc"&gt;.thumb_func&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="PreProc"&gt;.global&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;&lt;span class="Function"&gt;main:&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Lastly, we need to make sure our program is what runs when our microcontroller
powers on.  The reset vector is the location the CPU will go to find
the first instruction it will execute after being reset.&lt;/p&gt;
&lt;p&gt;What we’re doing below is putting the address of &lt;code&gt;main&lt;/code&gt; into the reset vector
so that when our board turns on, it will go to that address and start running
our code to flash the LED.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="PreProc"&gt;.section&lt;/span&gt; &lt;span class="op_lv0"&gt;.&lt;/span&gt;vector_table&lt;span class="op_lv0"&gt;.&lt;/span&gt;reset_vector
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="PreProc"&gt;.word&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;We now have our final asm file:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;.syntax&lt;/span&gt; &lt;span class="Function"&gt;unified&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;&lt;span class="PreProc"&gt;.thumb_func&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;&lt;span class="PreProc"&gt;.global&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;&lt;span class="Function"&gt;main:&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Store&lt;/span&gt; &lt;span class="Function"&gt;RCC&lt;/span&gt; &lt;span class="Function"&gt;base&lt;/span&gt; &lt;span class="Function"&gt;address&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x3800&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x4002&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Turn&lt;/span&gt; &lt;span class="Function"&gt;on&lt;/span&gt; &lt;span class="Function"&gt;GPIOA&lt;/span&gt; &lt;span class="Function"&gt;clock&lt;/span&gt; &lt;span class="Function"&gt;by&lt;/span&gt; &lt;span class="Function"&gt;setting&lt;/span&gt; &lt;span class="Function"&gt;bit&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;AHB1ENR&lt;/span&gt; &lt;span class="Function"&gt;register&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x01&lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x30&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Store&lt;/span&gt; &lt;span class="Function"&gt;start&lt;/span&gt; &lt;span class="Function"&gt;address&lt;/span&gt; &lt;span class="Function"&gt;of&lt;/span&gt; &lt;span class="Function"&gt;GPIOA&lt;/span&gt; &lt;span class="Function"&gt;registers&lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0000&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x4002&lt;/span&gt;
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Use&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_MODER&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;make&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt; &lt;span class="Function"&gt;an&lt;/span&gt; &lt;span class="Function"&gt;output&lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0000&lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0xA801&lt;/span&gt;
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;&lt;span class="op_lv0"&gt;.&lt;/span&gt;loop&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Set&lt;/span&gt; &lt;span class="Function"&gt;BR8&lt;/span&gt; &lt;span class="Function"&gt;field&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_BSRR&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;clear&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt;
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0000&lt;/span&gt;
&lt;span id="L26" class="LineNr"&gt;26 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0100&lt;/span&gt;
&lt;span id="L27" class="LineNr"&gt;27 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x18&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L28" class="LineNr"&gt;28 &lt;/span&gt;
&lt;span id="L29" class="LineNr"&gt;29 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Delay&lt;/span&gt;
&lt;span id="L30" class="LineNr"&gt;30 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x3500&lt;/span&gt;
&lt;span id="L31" class="LineNr"&gt;31 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x000c&lt;/span&gt;
&lt;span id="L32" class="LineNr"&gt;32 &lt;/span&gt;&lt;span class="op_lv0"&gt;.&lt;/span&gt;L&lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L33" class="LineNr"&gt;33 &lt;/span&gt;    &lt;span class="Keyword"&gt;subs&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0001&lt;/span&gt;
&lt;span id="L34" class="LineNr"&gt;34 &lt;/span&gt;    &lt;span class="Keyword"&gt;bne&lt;/span&gt; &lt;span class="op_lv0"&gt;.&lt;/span&gt;L&lt;span class="Constant"&gt;1&lt;/span&gt;
&lt;span id="L35" class="LineNr"&gt;35 &lt;/span&gt;
&lt;span id="L36" class="LineNr"&gt;36 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Set&lt;/span&gt; &lt;span class="Function"&gt;BS8&lt;/span&gt; &lt;span class="Function"&gt;field&lt;/span&gt; &lt;span class="Function"&gt;in&lt;/span&gt; &lt;span class="Function"&gt;GPIOA_BSRR&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Function"&gt;to&lt;/span&gt; &lt;span class="Function"&gt;set&lt;/span&gt; &lt;span class="Function"&gt;GPIOA8&lt;/span&gt;
&lt;span id="L37" class="LineNr"&gt;37 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0100&lt;/span&gt;
&lt;span id="L38" class="LineNr"&gt;38 &lt;/span&gt;    &lt;span class="Keyword"&gt;str&lt;/span&gt;  &lt;span class="Type"&gt;r1&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="lv12c"&gt;[&lt;/span&gt;&lt;span class="Type"&gt;r0&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x18&lt;/span&gt;&lt;span class="lv12c"&gt;]&lt;/span&gt;
&lt;span id="L39" class="LineNr"&gt;39 &lt;/span&gt;
&lt;span id="L40" class="LineNr"&gt;40 &lt;/span&gt;    &lt;span class="op_lv0"&gt;@&lt;/span&gt; &lt;span class="Function"&gt;Delay&lt;/span&gt;
&lt;span id="L41" class="LineNr"&gt;41 &lt;/span&gt;    &lt;span class="Keyword"&gt;movw&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x3500&lt;/span&gt;
&lt;span id="L42" class="LineNr"&gt;42 &lt;/span&gt;    &lt;span class="Keyword"&gt;movt&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x000c&lt;/span&gt;
&lt;span id="L43" class="LineNr"&gt;43 &lt;/span&gt;&lt;span class="op_lv0"&gt;.&lt;/span&gt;L&lt;span class="Constant"&gt;2&lt;/span&gt;&lt;span class="op_lv0"&gt;:&lt;/span&gt;
&lt;span id="L44" class="LineNr"&gt;44 &lt;/span&gt;    &lt;span class="Keyword"&gt;subs&lt;/span&gt; &lt;span class="Type"&gt;r2&lt;/span&gt;&lt;span class="op_lv0"&gt;,&lt;/span&gt; &lt;span class="Constant"&gt;#0x0001&lt;/span&gt;
&lt;span id="L45" class="LineNr"&gt;45 &lt;/span&gt;    &lt;span class="Keyword"&gt;bne&lt;/span&gt; &lt;span class="op_lv0"&gt;.&lt;/span&gt;L&lt;span class="Constant"&gt;2&lt;/span&gt;
&lt;span id="L46" class="LineNr"&gt;46 &lt;/span&gt;
&lt;span id="L47" class="LineNr"&gt;47 &lt;/span&gt;    &lt;span class="Keyword"&gt;b&lt;/span&gt; &lt;span class="op_lv0"&gt;.&lt;/span&gt;loop
&lt;span id="L48" class="LineNr"&gt;48 &lt;/span&gt;
&lt;span id="L49" class="LineNr"&gt;49 &lt;/span&gt;&lt;span class="PreProc"&gt;.section&lt;/span&gt; &lt;span class="op_lv0"&gt;.&lt;/span&gt;vector_table&lt;span class="op_lv0"&gt;.&lt;/span&gt;reset_vector
&lt;span id="L50" class="LineNr"&gt;50 &lt;/span&gt;&lt;span class="PreProc"&gt;.word&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;h1&gt;Building our code and flashing our target&lt;/h1&gt;
&lt;p&gt;We use an &lt;em&gt;assembler&lt;/em&gt; to turn our assembly into an object file, e.g.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;arm-none-eabi-as -mcpu=cortex-m4 toggle.s -c -o output/toggle.o&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then we use a linker to make an executable. We need a custom linker script to
tell the linker where RAM and flash start on our target. Here's what I used:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Keyword"&gt;ENTRY&lt;/span&gt;&lt;span class="lv12c"&gt;(&lt;/span&gt;main&lt;span class="lv12c"&gt;)&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;&lt;span class="PreProc"&gt;MEMORY&lt;/span&gt; &lt;span class="lv12c"&gt;{&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;    FLASH   &lt;span class="op_lv12"&gt;:&lt;/span&gt; &lt;span class="Identifier"&gt;ORIGIN&lt;/span&gt; &lt;span class="op_lv12"&gt;=&lt;/span&gt; &lt;span class="Number"&gt;0x08000000&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;LENGTH&lt;/span&gt; &lt;span class="op_lv12"&gt;=&lt;/span&gt; &lt;span class="Number"&gt;128&lt;/span&gt;&lt;span class="PreProc"&gt;K&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;    RAM     &lt;span class="op_lv12"&gt;:&lt;/span&gt; &lt;span class="Identifier"&gt;ORIGIN&lt;/span&gt; &lt;span class="op_lv12"&gt;=&lt;/span&gt; &lt;span class="Number"&gt;0x20000000&lt;/span&gt;&lt;span class="op_lv12"&gt;,&lt;/span&gt; &lt;span class="Identifier"&gt;LENGTH&lt;/span&gt; &lt;span class="op_lv12"&gt;=&lt;/span&gt; &lt;span class="Number"&gt;128&lt;/span&gt;&lt;span class="PreProc"&gt;K&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;&lt;span class="lv12c"&gt;}&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;&lt;span class="PreProc"&gt;SECTIONS&lt;/span&gt; &lt;span class="lv12c"&gt;{&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="Comment"&gt;/\* Vector table is first thing in flash \*/&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;    &lt;span class="op_lv12"&gt;.&lt;/span&gt;vector_table &lt;span class="Identifier"&gt;ORIGIN&lt;/span&gt;&lt;span class="lv11c"&gt;(&lt;/span&gt;FLASH&lt;span class="lv11c"&gt;)&lt;/span&gt; &lt;span class="op_lv12"&gt;:&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;    &lt;span class="lv11c"&gt;{&lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;        &lt;span class="Comment"&gt;/\* Initial stack pointer \*/&lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;        &lt;span class="Type"&gt;LONG&lt;/span&gt;&lt;span class="lv10c"&gt;(&lt;/span&gt;&lt;span class="Identifier"&gt;ORIGIN&lt;/span&gt;&lt;span class="lv9c"&gt;(&lt;/span&gt;RAM&lt;span class="lv9c"&gt;)&lt;/span&gt; &lt;span class="op_lv10"&gt;+&lt;/span&gt; &lt;span class="Identifier"&gt;LENGTH&lt;/span&gt;&lt;span class="lv9c"&gt;(&lt;/span&gt;RAM&lt;span class="lv9c"&gt;)&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;;&lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;        &lt;span class="Comment"&gt;/\* Rest of vector table \*/&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;        &lt;span class="Keyword"&gt;KEEP&lt;/span&gt;&lt;span class="lv10c"&gt;(&lt;/span&gt;&lt;span class="op_lv10"&gt;\*&lt;/span&gt;&lt;span class="lv9c"&gt;(&lt;/span&gt;&lt;span class="op_lv9"&gt;.&lt;/span&gt;vector_table&lt;span class="lv9c"&gt;)&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;;&lt;/span&gt;
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;    &lt;span class="lv11c"&gt;}&lt;/span&gt; &lt;span class="op_lv12"&gt;&amp;gt;&lt;/span&gt; FLASH
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;    &lt;span class="Comment"&gt;/\* text section contains executable code \*/&lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;    &lt;span class="op_lv12"&gt;.&lt;/span&gt;text &lt;span class="Identifier"&gt;ADDR&lt;/span&gt;&lt;span class="lv11c"&gt;(&lt;/span&gt;&lt;span class="op_lv11"&gt;.&lt;/span&gt;vector_table&lt;span class="lv11c"&gt;)&lt;/span&gt; &lt;span class="op_lv12"&gt;+&lt;/span&gt; &lt;span class="Identifier"&gt;SIZEOF&lt;/span&gt;&lt;span class="lv11c"&gt;(&lt;/span&gt;&lt;span class="op_lv11"&gt;.&lt;/span&gt;vector_table&lt;span class="lv11c"&gt;)&lt;/span&gt; &lt;span class="op_lv12"&gt;:&lt;/span&gt;
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;    &lt;span class="lv11c"&gt;{&lt;/span&gt;
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;        &lt;span class="op_lv11"&gt;\*&lt;/span&gt;&lt;span class="lv10c"&gt;(&lt;/span&gt;&lt;span class="op_lv10"&gt;.&lt;/span&gt;text &lt;span class="op_lv10"&gt;.&lt;/span&gt;text&lt;span class="op_lv10"&gt;.\*&lt;/span&gt;&lt;span class="lv10c"&gt;)&lt;/span&gt;&lt;span class="op_lv11"&gt;;&lt;/span&gt;
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;    &lt;span class="lv11c"&gt;}&lt;/span&gt; &lt;span class="op_lv12"&gt;&amp;gt;&lt;/span&gt; FLASH
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;&lt;span class="lv12c"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Then we can call the linker:
&lt;code&gt;arm-none-eabi-ld -T link.ld output/toggle.o -o output/toggle&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I'm using a &lt;a href="https://github.com/blacksphere/blackmagic/wiki" target="_blank"&gt;Black Magic probe&lt;/a&gt;
to flash my 1bitsy. I can talk to the probe over gdb:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;gdb-multiarch&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;--batch&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-ex&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tar ext /dev/serial/by-id/example&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-ex&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mon tpwr en&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-ex&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mon swdp_scan&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;                     &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-ex&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;att 1&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;                             &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-ex&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;load&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;                              &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-ex&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;start&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;                             &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-ex&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;detach&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;                            &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;output/toggle
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Voila:
&lt;img src="/images/led-flash/blinky.gif" width="300" alt="A gif of the LED flashing" class=callout&gt;&lt;/p&gt;
&lt;h1&gt;Resources&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You can check out my 
&lt;a href="https://github.com/lochsh/gpio-toggle-exercise" target="_blank"&gt;GPIO toggling exercise&lt;/a&gt;
which talks you through the assembly here in a little more detail, and provides
a Dockerfile for emulating the target chip. I'll have a (shorter) blog post
about the emulation soon.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Azeria Labs have an &lt;a href="https://azeria-labs.com/writing-arm-assembly-part-1/" target="_blank"&gt;excellent guide&lt;/a&gt; to ARM assembly that goes into more
detail than I have, though assumes a bit more knowledge about computer
architecture.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a href="http://infocenter.arm.com/help/topic/com.arm.doc.dui0553b/DUI0553.pdf" target="_blank"&gt;Cortex M4 User Guide&lt;/a&gt; is a good technical reference for the assembly written here&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/></entry><entry><title>Let's break CPython together, for fun and mischief</title><link href="https://mcla.ug/cpython-hackage.html" rel="alternate"/><published>2019-10-13T00:00:00+01:00</published><updated>2019-10-13T00:00:00+01:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2019-10-13:/cpython-hackage.html</id><summary type="html">&lt;p&gt;I promise that nothing we do here will be useful.&lt;/p&gt;
&lt;p&gt;But I promise it will be entertaining, and (hopefully) educational:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;if you don't know anything about the CPython internals, you're about to
learn (a bit)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;if you do know about the CPython internals, you're hopefully about to
learn some new …&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;I promise that nothing we do here will be useful.&lt;/p&gt;
&lt;p&gt;But I promise it will be entertaining, and (hopefully) educational:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;if you don't know anything about the CPython internals, you're about to
learn (a bit)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;if you do know about the CPython internals, you're hopefully about to
learn some new ways to abuse them 😉&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Clarification&lt;/h2&gt;
&lt;p&gt;Before we proceed to hackage, let me make sure it's clear what I'm talking
about when I say "CPython internals". CPython is the reference implementation
of Python, and it's what most people use. It's what comes as standard on any
system I've ever used.&lt;/p&gt;
&lt;p&gt;A Python implementation includes the interpreter, the built-in types and the
standard library. With CPython, apart from much of the standard library which
is in Python, this is all written in C. There are other implementations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PyPy is written in Python itself and has a JIT compiler, it's really fast&lt;/li&gt;
&lt;li&gt;Jython runs on the JVM&lt;/li&gt;
&lt;li&gt;IronPython runs on .NET the Microsoft framework&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everything we do here is exploiting the specific implementation details
of CPython.&lt;/p&gt;
&lt;h3&gt;YMMV&lt;/h3&gt;
&lt;p&gt;Please bear in mind that Python was not designed to do the things we're going
to do, and some of the fun things that worked with the version of Python I used
here, my operating system, &amp;amp;c., might end up segfaulting for you. Running stuff
in ipython rather than the standard REPL will also likely end up with more
issues occurring when things are hacked.&lt;/p&gt;
&lt;h2&gt;To whet your appetite&lt;/h2&gt;
&lt;p&gt;Let's have a look at the Python language reference. The first two sentences of
the &lt;a href="https://docs.python.org/3/reference/datamodel.html"&gt;data model&lt;/a&gt; say this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Objects are Python’s abstraction for data. All data in a Python program is
represented by objects or by relations between objects.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In CPython a Python object is defined in the
&lt;a href="https://github.com/python/cpython/blob/10e5c66789a06dc9015a24968e96e77a75725a7a/Include/object.h#L104"&gt;&lt;code&gt;PyObject&lt;/code&gt;&lt;/a&gt;
struct:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Type"&gt;typedef&lt;/span&gt; &lt;span
class="Type"&gt;struct&lt;/span&gt; _object {
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    _PyObject_HEAD_EXTRA
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    Py_ssize_t ob_refcnt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;    &lt;span class="Type"&gt;struct&lt;/span&gt; _typeobject *ob_type;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;} PyObject;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;(The first bit here, &lt;code&gt;_PyObject_HEAD_EXTRA&lt;/code&gt;, is only valid when compiling Python
with a special tracing debugging feature, so don't worry about it.)&lt;/p&gt;
&lt;p&gt;We have the reference count &lt;code&gt;ob_refcnt&lt;/code&gt;, which is used for memory management
and tells us how many other objects are referencing this one. When the
reference count of an object is zero, its memory and resources can be freed by
the garbage collector.&lt;/p&gt;
&lt;p&gt;We also have the type information, &lt;code&gt;ob_type&lt;/code&gt;, which tells us how to interact
with the object, what its behaviour is, what data it contains.&lt;/p&gt;
&lt;p&gt;Going back to the data model:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every object has an identity, a type and a value. An object’s identity never
changes once it has been created; you may think of it as the object’s address
in memory. The ‘is’ operator compares the identity of two objects; the id()
function returns an integer representing its identity.&lt;/p&gt;
&lt;p&gt;CPython implementation detail: For CPython, id(x) is the memory address where
x is stored.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So what I'd expect CPython to do is dynamically allocate memory for a new
&lt;code&gt;PyObject&lt;/code&gt; each time we create a new object.&lt;/p&gt;
&lt;p&gt;Let's test this out with some integers:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; x = &lt;span class="Number"&gt;500&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; y = &lt;span class="Number"&gt;500&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; x &lt;span class="Statement"&gt;is&lt;/span&gt; y
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="Function"&gt;False&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;That makes sense: a new &lt;code&gt;PyObject&lt;/code&gt; has been allocated for each variable we've
made here, and so they are at different places in memory. But what if we use
smaller integers?&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; x = &lt;span class="Number"&gt;5&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; y = &lt;span class="Number"&gt;5&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; x &lt;span class="Statement"&gt;is&lt;/span&gt; y
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="Function"&gt;True&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;How surprising! Let's have a look in the &lt;a href="https://github.com/python/cpython/blob/10e5c66789a06dc9015a24968e96e77a75725a7a/Objects/longobject.c#L38"&gt;CPython
source&lt;/a&gt;
to see why this might be:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;#ifndef NSMALLPOSINTS&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;&lt;span class="PreProc"&gt;#define NSMALLPOSINTS           &lt;/span&gt;&lt;span class="Number"&gt;257&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;&lt;span class="PreProc"&gt;#endif&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;&lt;span class="PreProc"&gt;#ifndef NSMALLNEGINTS&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;&lt;span class="PreProc"&gt;#define NSMALLNEGINTS           &lt;/span&gt;&lt;span class="Number"&gt;5&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;&lt;span class="PreProc"&gt;#endif&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;&lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; Small integers are preallocated in this array so that they&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;&lt;span class="Comment"&gt;   can be shared.&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;&lt;span class="Comment"&gt;   The integers that are preallocated are those in the range&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;&lt;span class="Comment"&gt;   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).&lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;&lt;span class="Type"&gt;static&lt;/span&gt; PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;So it seems integers between -5 and 256 inclusive are statically allocated in a
big old array!  This is an optimisation that CPython has chosen to do -- the
idea is that these integers are going to be used a lot, and it would be time
consuming to allocate new memory every time.&lt;/p&gt;
&lt;p&gt;But...if that means some integers have a defined place in memory, can
we...corrupt that memory?&lt;/p&gt;
&lt;h2&gt;import ctypes&lt;/h2&gt;
&lt;p&gt;&lt;img alt="ctypes" src="/images/goosebumpsctypes.jpg" title="Someone whispering 'import ctypes' and goosebumps appearing on the arm of the listener"&gt;&lt;/p&gt;
&lt;p&gt;Most good CPython shenanigans begins with importing ctypes, which is Python's
standard C foreign function interface. An FFI allows different languages to
interoperate. ctypes provides C compatible data types and allows calling
functions from shared libraries and such.&lt;/p&gt;
&lt;p&gt;The ctypes docs tell us about the function
&lt;a href="https://docs.python.org/3.7/library/ctypes.html#ctypes.memmove"&gt;&lt;code&gt;memmove&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ctypes.memmove(dst, src, count)&lt;/p&gt;
&lt;p&gt;Same as the standard C memmove library function: copies count bytes from
   src to dst. dst and src must be integers or ctypes instances that can be
   converted to pointers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So what if we copied the memory where 6 is to where 5 is?&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="PreProc"&gt;import&lt;/span&gt; ctypes
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="PreProc"&gt;import&lt;/span&gt; sys
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; ctypes.memmove(&lt;span class="Function"&gt;id&lt;/span&gt;(&lt;span class="Number"&gt;5&lt;/span&gt;), &lt;span class="Function"&gt;id&lt;/span&gt;(&lt;span class="Number"&gt;6&lt;/span&gt;), sys.getsizeof(&lt;span class="Number"&gt;5&lt;/span&gt;))
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Number"&gt;5&lt;/span&gt; + &lt;span class="Number"&gt;5&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;&lt;span class="Number"&gt;12&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;What fun! But this is small fry stuff. We can do more. We have ambition.&lt;/p&gt;
&lt;h2&gt;Ambition&lt;/h2&gt;
&lt;p&gt;I don't what to change one integer. I want to change ALL the integers.&lt;/p&gt;
&lt;p&gt;What if we changed what happens when you add integers together? What if we made
it subtract instead?&lt;/p&gt;
&lt;p&gt;&lt;img alt="mischief" src="/images/thearm.gif" title="The Arm from Twin Peaks rubbing his hands together mischeviously"&gt;&lt;/p&gt;
&lt;p&gt;The way operator resolution works in Python is that the corresponding "magic
method" or "dunder method" (for double underscores) is called. For example &lt;code&gt;x +
y&lt;/code&gt; will become &lt;code&gt;x.__add__(y)&lt;/code&gt;. So the &lt;code&gt;int.__add__&lt;/code&gt; method is going to be our
target for mischevious hackage.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;fake_add&lt;/span&gt;(x, y):
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; x - y
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Function"&gt;int&lt;/span&gt;.__add__ = fake_add
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="Type"&gt;TypeError&lt;/span&gt;: can't set attributes of built-in/extension type &lt;/span&gt;&lt;span class="String"&gt;'&lt;/span&gt;&lt;span class="Function"&gt;int&lt;/span&gt;&lt;span class="String"&gt;'&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Annoying, but unsurprising. Python is permissive in the sense that it doesn't
have access modifiers like C++ or Java &amp;ndash; you can't really define private
attributes of a class. But you can't do just anything, and patching built-ins like
this is one of the things Python prevents us from doing &amp;ndash; unless we try very
hard.&lt;/p&gt;
&lt;p&gt;So what can we try instead?  All attribute resolution comes down to looking up
attribute names in an object's dictionary. For example, &lt;code&gt;x.y&lt;/code&gt; would resolve to
&lt;code&gt;x.__dict__["y"]&lt;/code&gt;&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;. What if we try accessing &lt;code&gt;int.__add__&lt;/code&gt; that way?&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Function"&gt;int&lt;/span&gt;.__dict__[&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;__add__&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;] = fake_add
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="Type"&gt;TypeError&lt;/span&gt;: &lt;span class="String"&gt;'&lt;/span&gt;&lt;span class="String"&gt;mappingproxy&lt;/span&gt;&lt;span class="String"&gt;'&lt;/span&gt; &lt;span class="Function"&gt;object&lt;/span&gt; does &lt;span class="Statement"&gt;not&lt;/span&gt; support item assignment
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Tarnation. But of course, we knew it would not be as easy as this. Perhaps lesser
programmers would give up here. "It's not allowed," they might say. But we are
strong and we are determined.&lt;/p&gt;
&lt;p&gt;What is this
&lt;a href="https://docs.python.org/3/library/types.html#types.MappingProxyType"&gt;mappingproxy&lt;/a&gt; the interpreter speaks of?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Read-only proxy of a mapping.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ok, so this is just some cast over the actual dictionary. If we can cast it to
a dictionary, we can assign to it. But doing this with a Python cast is just
creating a copy:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span
class="Function"&gt;dict&lt;/span&gt;(&lt;span class="Function"&gt;int&lt;/span&gt;.__dict__)[&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;__add__&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;] = fake_add
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Number"&gt;1&lt;/span&gt; + &lt;span class="Number"&gt;5&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&lt;span class="Number"&gt;6&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; (&lt;span class="Number"&gt;1&lt;/span&gt;).__add__(&lt;span class="Number"&gt;5&lt;/span&gt;)
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;&lt;span class="Number"&gt;6&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Function"&gt;int&lt;/span&gt;.__add__ == fake_add
&lt;span id="L7" class="LineNr"&gt;7 &lt;/span&gt;&lt;span class="Function"&gt;False&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;We need to go deeper. Let's look at the &lt;a href="https://github.com/python/cpython/blob/10e5c66789a06dc9015a24968e96e77a75725a7a/Objects/descrobject.c#L954"&gt;CPython
source&lt;/a&gt; for the mappingproxy type.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Type"&gt;typedef&lt;/span&gt; &lt;span class="Type"&gt;struct&lt;/span&gt; {
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;    PyObject_HEAD
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;    PyObject *mapping;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;} mappingproxyobject;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;&lt;span class="Type"&gt;static&lt;/span&gt; PyMappingMethods mappingproxy_as_mapping = {
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;    (lenfunc)mappingproxy_len,                  &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; mp_length &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    (binaryfunc)mappingproxy_getitem,           &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; mp_subscript &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="Number"&gt;0&lt;/span&gt;,                                          &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; mp_ass_subscript &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;};
&lt;/pre&gt;
&lt;/body&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;The &lt;code&gt;PyMappingMethods&lt;/code&gt; of a type tell us how it behaves as a mapping: what does
&lt;code&gt;x[key]&lt;/code&gt; do (&lt;code&gt;mp_subscript&lt;/code&gt;)? What does &lt;code&gt;x[key] = y&lt;/code&gt; do (&lt;code&gt;mp_ass_subscript&lt;/code&gt;)?&lt;/p&gt;
&lt;p&gt;What this is telling us is that the mapping proxy is basically a wrapper around
a normal dictionary with the function pointer to the subscript assignment
method set to NULL.&lt;/p&gt;
&lt;p&gt;We can use ctypes to cast this and reveal the underlying dictionary.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; ctypes
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;&lt;span class="Statement"&gt;class&lt;/span&gt; &lt;span class="Function"&gt;PyObject&lt;/span&gt;(ctypes.Structure):
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;    &lt;span class="Statement"&gt;pass&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;PyObject._fields_ = [
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    (&lt;span class="String"&gt;'&lt;/span&gt;&lt;span class="String"&gt;ob_refcnt&lt;/span&gt;&lt;span class="String"&gt;'&lt;/span&gt;, ctypes.c_ssize_t)
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;    (&lt;span class="String"&gt;'&lt;/span&gt;&lt;span class="String"&gt;ob_type&lt;/span&gt;&lt;span class="String"&gt;'&lt;/span&gt;, ctypes.POINTER(PyObject))
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;]
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;&lt;span class="Statement"&gt;class&lt;/span&gt; &lt;span class="Function"&gt;MappingProxy&lt;/span&gt;(PyObject):
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;    _fields_ = [(&lt;span class="String"&gt;'&lt;/span&gt;&lt;span class="String"&gt;dict&lt;/span&gt;&lt;span class="String"&gt;'&lt;/span&gt;, ctypes.POINTER(PyObject))]
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;The trouble is, once we have the dict as a PyObject pointer, how do we get it
back to being a plain old Python dict?  It's no good doing this:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; MappingProxy.from_address(&lt;span class="Function"&gt;id&lt;/span&gt;(&lt;span class="Function"&gt;int&lt;/span&gt;.__dict__)).dict
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&amp;lt;LP_PyObject at &lt;span class="Number"&gt;0x7f6e98c8e7b8&lt;/span&gt;&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;if we have no way to interpret this as a dict. We can use this pleasing wee
trick from the CPython API, courtesy of &lt;a href="http://lucumr.pocoo.org/about/"&gt;Armin
Ronacher&lt;/a&gt;&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;  which will put it as a value into another existing
dictionary where it will be interpreted the same as any other object, then we
can extract it!&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;pyobj_cast&lt;/span&gt;(obj):
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; ctypes.cast(&lt;span class="Function"&gt;id&lt;/span&gt;(obj), ctypes.POINTER(PyObject)
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Function"&gt;get_dict&lt;/span&gt;(proxy):
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;    dict_as_pyobj = MappingProxy.from_address(&lt;span class="Function"&gt;id&lt;/span&gt;(proxy)).dict
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;    fence = {}
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    ctypes.pythonapi.PyDict_SetItem(
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;            pyobj_cast(fence),
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;            pyobj_cast(&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;victory&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;),
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;            dict_as_pyobj)
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; fence[&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;victory&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;]
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;int_dict = get_dict(&lt;span class="Function"&gt;int&lt;/span&gt;.__dict__)
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;int_dict[&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;__add__&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;] = fake_add
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Have we done it???&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Number"&gt;1&lt;/span&gt; + &lt;span class="Number"&gt;1&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="Number"&gt;2&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;D'oh! But wait a minute...&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; (&lt;span class="Number"&gt;1&lt;/span&gt;).__add__(&lt;span class="Number"&gt;1&lt;/span&gt;)
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="Number"&gt;0&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;What! But the data model says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;to evaluate the expression x + y, where x is an instance of a class that has
an __add__() method, x.__add__(y) is called&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We've been lied to...this is clearly not true! It seems CPython has some
shortcut in place.&lt;/p&gt;
&lt;p&gt;To be fair, they probably didn't think we'd ever find out this "lie" by
performing these shenanigans. We need to go yet deeper still to fulfill our
pointless quest. We &lt;em&gt;will&lt;/em&gt; have control of the builtins.&lt;/p&gt;
&lt;h2&gt;Full type mappings&lt;/h2&gt;
&lt;p&gt;Back to the CPython source. What is in this type information that's in the
PyObject struct we looked at earlier? The answer: lots of stuff that I am not going to put here, but the most
interesting parts for our purposes are the &lt;a href="https://github.com/python/cpython/blob/10e5c66789a06dc9015a24968e96e77a75725a7a/Doc/includes/typestruct.h#L16"&gt;method
suites&lt;/a&gt;:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Type"&gt;typedef&lt;/span&gt; &lt;span
class="Type"&gt;struct&lt;/span&gt; _typeobject {
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    ...
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    PyNumberMethods *tp_as_number;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;    PySequenceMethods *tp_as_sequence;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;    PyMappingMethods *tp_as_mapping;
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;    ...
&lt;span id="L7" class="LineNr"&gt;7 &lt;/span&gt;} PyTypeObject;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;This struct contains other structs defining the behaviour of the type
via function pointers. We're specifically interested in this
&lt;a href="https://github.com/python/cpython/blob/10e5c66789a06dc9015a24968e96e77a75725a7a/Include/cpython/object.h#L95"&gt;&lt;code&gt;tp_as_number&lt;/code&gt;&lt;/a&gt;
member. Its first member, &lt;code&gt;nb_add&lt;/code&gt;, is the function pointer to the add
method. This is what we want to overwrite. This is our new target.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Type"&gt;typedef&lt;/span&gt; &lt;span class="Type"&gt;struct&lt;/span&gt; {
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    binaryfunc nb_add;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    binaryfunc nb_subtract;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;    binaryfunc nb_multiply;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;    ...
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;} PyNumberMethods;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;So, like we made the ctypes mappings before, I want to do it for this entire
&lt;code&gt;PyTypeObject&lt;/code&gt; struct. Which is big...so I'm not putting it all here!&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; ctypes
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;&lt;span class="Statement"&gt;class&lt;/span&gt; &lt;span class="Function"&gt;PyObject&lt;/span&gt;(ctypes.Structure):
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;    &lt;span class="Statement"&gt;pass&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;&lt;span class="Statement"&gt;class&lt;/span&gt; &lt;span class="Function"&gt;PyTypeObject&lt;/span&gt;(ctypes.Structure):
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="Statement"&gt;pass&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;Py_ssize_t = ctypes.c_ssize_t
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;binaryfunc = ctypes.CFUNCTYPE(
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;        ctypes.POINTER(PyObject),
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;        ctypes.POINTER(PyObject),
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;        ctypes.POINTER(PyObject))
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;&lt;span class="Statement"&gt;class&lt;/span&gt; &lt;span class="Function"&gt;PyNumberMethods&lt;/span&gt;(ctypes.Structure):
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;    _fields_ = [
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;            (&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;nb_add&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;, binaryfunc),
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;            (&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;nb_subtract&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;, binaryfunc),
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;            (&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;nb_multiply&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;, binaryfunc),
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;            ...
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;
&lt;span id="L26" class="LineNr"&gt;26 &lt;/span&gt;PyTypeObject._fields_ = [
&lt;span id="L27" class="LineNr"&gt;27 &lt;/span&gt;        ...
&lt;span id="L28" class="LineNr"&gt;28 &lt;/span&gt;        (&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;tp_as_number&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;, ctypes.POINTER(PyNumberMethods)),
&lt;span id="L29" class="LineNr"&gt;29 &lt;/span&gt;        ...
&lt;span id="L30" class="LineNr"&gt;30 &lt;/span&gt;
&lt;span id="L31" class="LineNr"&gt;31 &lt;/span&gt;
&lt;span id="L32" class="LineNr"&gt;32 &lt;/span&gt;PyObject._fields_ = [
&lt;span id="L33" class="LineNr"&gt;33 &lt;/span&gt;        (&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;ob_refcnt&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;, Py_ssize_t),
&lt;span id="L34" class="LineNr"&gt;34 &lt;/span&gt;        (&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;ob_type&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;, ctypes.POINTER(PyTypeObject))]
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;So here we've basically made a Python mapping of the structs we have in C. If
we cast our Python &lt;code&gt;int&lt;/code&gt; type to the equivalent type struct, we'll reveal the
secrets usually hidden from us.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; PyLong_Type = ctypes.cast(&lt;span class="Function"&gt;id&lt;/span&gt;(&lt;span class="Function"&gt;int&lt;/span&gt;), ctypes.POINTER(PyTypeObject)).contents
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; PyLong_Type.tp_as_number.contents.nb_add = PyLong_Type.tp_as_number.contents.nb_subtract
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Number"&gt;10&lt;/span&gt; + &lt;span class="Number"&gt;4&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="Number"&gt;6&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Number"&gt;1&lt;/span&gt; + &lt;span class="Number"&gt;1&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;&lt;span class="Number"&gt;0&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt;7 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Number"&gt;1&lt;/span&gt; + &lt;span class="Number"&gt;3&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt;8 &lt;/span&gt;-&lt;span class="Number"&gt;2&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;We did it!!! Incredible.&lt;/p&gt;
&lt;p&gt;But now we know how to patch built-ins...what if we went further? What if we
added functionality that wasn't there before, rather than altering existing
functionality?&lt;/p&gt;
&lt;h2&gt;Nice immutable string you got there. It would be a shame if something should...happen to it 😏&lt;/h2&gt;
&lt;p&gt;In Python, strings are immutable. You can't go in and change one of the
characters &amp;ndash; you have to create a new string object. When you add characters
to an existing string variable, a new string object is created.&lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;What if we made strings mutable?&lt;/p&gt;
&lt;p&gt;Let's have a look at &lt;code&gt;PyUnicode_Type&lt;/code&gt; in the &lt;a href="https://github.com/python/cpython/blob/10e5c66789a06dc9015a24968e96e77a75725a7a/Objects/unicodeobject.c"&gt;CPython
source&lt;/a&gt;...and
then swiftly look away from all 16k lines of it cos it's distressingly complex
as it has to handle unicode and all its complexities as well as ASCII: good
times. We want to find the
&lt;a href="https://github.com/python/cpython/blob/10e5c66789a06dc9015a24968e96e77a75725a7a/Objects/unicodeobject.c#L14126"&gt;&lt;code&gt;tp_as_mapping&lt;/code&gt;&lt;/a&gt; member of the &lt;code&gt;PyUnicode_Type&lt;/code&gt;
struct:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Type"&gt;static&lt;/span&gt; PyMappingMethods unicode_as_mapping = {
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    (lenfunc)unicode_length,        &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; mp_length &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    (binaryfunc)unicode_subscript,  &lt;span
class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; mp_subscript &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;    (objobjargproc)&lt;span
class="Number"&gt;0&lt;/span&gt;,               &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; mp_ass_subscript &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;};
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;We want to create a new function to point to from the &lt;code&gt;mp_ass_subscript&lt;/code&gt;
member. Here's my extremely hacked one which wouldn't handle every case, not at
all. But I think it's going to allow us to do what we want.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;&lt;span class="Function"&gt;unicode_ass_subscript&lt;/span&gt;(PyUnicodeObject* self, PyObject* item, PyObject* value)
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;{
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;    Py_ssize_t i = ((PyLongObject*)(item))-&amp;gt;ob_digit[&lt;span class="Number"&gt;0&lt;/span&gt;];
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;    &lt;span class="Type"&gt;unsigned&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; kind = ((PyASCIIObject*)(self))-&amp;gt;state.kind;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;    &lt;span class="Type"&gt;char&lt;/span&gt;* data = ((&lt;span class="Type"&gt;char&lt;/span&gt;*)((PyASCIIObject*)(self) + &lt;span class="Number"&gt;1&lt;/span&gt;));
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;    &lt;span class="Type"&gt;char&lt;/span&gt;* new_data = ((&lt;span class="Type"&gt;char&lt;/span&gt;*)((PyASCIIObject*)(value) + &lt;span class="Number"&gt;1&lt;/span&gt;));
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    *(data + kind * i) = *new_data;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;}
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;&lt;span class="Type"&gt;static&lt;/span&gt; PyMappingMethods unicode_as_mapping = {
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;    (lenfunc)unicode_length,                 &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; mp_length &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;    (binaryfunc)unicode_subscript,           &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; mp_subscript &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;    (objobjargproc)unicode_ass_subscript,    &lt;span class="Comment"&gt;/*&lt;/span&gt;&lt;span class="Comment"&gt; mp_ass_subscript &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;};
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;I don't want to just change the source code of the Python binary I'm using.
That is cheating. I want to break Python from the &lt;em&gt;inside&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;But I &lt;em&gt;can&lt;/em&gt; use this to get the machine code that I want to replace the
subscript assignment function with. (This is now just stupid compared to what
we were doing before...and not at all portable. But we are doing it.).&lt;/p&gt;
&lt;p&gt;First, I built CPython with this new source code in there. I can retrieve the
machine code generated by our new function using &lt;code&gt;objdump&lt;/code&gt;:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;objdump Objects/unicodeobject.o
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Number"&gt;00000000000000&lt;/span&gt;&lt;span class="Identifier"&gt;f4&lt;/span&gt; &amp;lt;&lt;span class="Identifier"&gt;unicode_ass_subscript&lt;/span&gt;&amp;gt;:
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;      &lt;span class="Identifier"&gt;f4&lt;/span&gt;:   &lt;span class="Number"&gt;8&lt;/span&gt;&lt;span class="Identifier"&gt;b&lt;/span&gt; &lt;span class="Number"&gt;4&lt;/span&gt;&lt;span class="Identifier"&gt;e&lt;/span&gt; &lt;span class="Number"&gt;18&lt;/span&gt;                &lt;span class="Identifier"&gt;mov&lt;/span&gt;    &lt;span class="Number"&gt;0x18&lt;/span&gt;(%&lt;span class="Identifier"&gt;rsi&lt;/span&gt;),%&lt;span class="Identifier"&gt;ecx&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;      &lt;span class="Identifier"&gt;f7&lt;/span&gt;:   0&lt;span class="Identifier"&gt;f&lt;/span&gt; &lt;span class="Identifier"&gt;b6&lt;/span&gt; &lt;span class="Number"&gt;47&lt;/span&gt; &lt;span class="Number"&gt;20&lt;/span&gt;             &lt;span class="Identifier"&gt;movzbl&lt;/span&gt; &lt;span class="Number"&gt;0x20&lt;/span&gt;(%&lt;span class="Identifier"&gt;rdi&lt;/span&gt;),%&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;      &lt;span class="Identifier"&gt;fb&lt;/span&gt;:   &lt;span class="Identifier"&gt;c0&lt;/span&gt; &lt;span class="Identifier"&gt;e8&lt;/span&gt; &lt;span class="Number"&gt;02 &lt;/span&gt;               &lt;span class="Identifier"&gt;shr&lt;/span&gt;    $&lt;span class="Number"&gt;0x2&lt;/span&gt;,%&lt;span class="Identifier"&gt;al&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;      &lt;span class="Identifier"&gt;fe&lt;/span&gt;:   &lt;span class="Number"&gt;83&lt;/span&gt; &lt;span class="Identifier"&gt;e0&lt;/span&gt; &lt;span class="Number"&gt;07 &lt;/span&gt;               &lt;span class="Identifier"&gt;and&lt;/span&gt;    $&lt;span class="Number"&gt;0x7&lt;/span&gt;,%&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;     &lt;span class="Number"&gt;101&lt;/span&gt;:   &lt;span class="Number"&gt;48&lt;/span&gt; 0&lt;span class="Identifier"&gt;f&lt;/span&gt; &lt;span class="Identifier"&gt;af&lt;/span&gt; &lt;span class="Identifier"&gt;c1&lt;/span&gt;             &lt;span class="Identifier"&gt;imul&lt;/span&gt;   %&lt;span class="Identifier"&gt;rcx&lt;/span&gt;,%&lt;span class="Identifier"&gt;rax&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;     &lt;span class="Number"&gt;105&lt;/span&gt;:   0&lt;span class="Identifier"&gt;f&lt;/span&gt; &lt;span class="Identifier"&gt;b6&lt;/span&gt; &lt;span class="Number"&gt;52&lt;/span&gt; &lt;span class="Number"&gt;30&lt;/span&gt;             &lt;span class="Identifier"&gt;movzbl&lt;/span&gt; &lt;span class="Number"&gt;0x30&lt;/span&gt;(%&lt;span class="Identifier"&gt;rdx&lt;/span&gt;),%&lt;span class="Identifier"&gt;edx&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;     &lt;span class="Number"&gt;109&lt;/span&gt;:   &lt;span class="Number"&gt;88&lt;/span&gt; &lt;span class="Number"&gt;54&lt;/span&gt; &lt;span class="Number"&gt;07 30&lt;/span&gt;             &lt;span class="Identifier"&gt;mov&lt;/span&gt;    %&lt;span class="Identifier"&gt;dl&lt;/span&gt;,&lt;span class="Number"&gt;0x30&lt;/span&gt;(%&lt;span class="Identifier"&gt;rdi&lt;/span&gt;,%&lt;span class="Identifier"&gt;rax&lt;/span&gt;,&lt;span class="Number"&gt;1&lt;/span&gt;)
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;     &lt;span class="Number"&gt;10&lt;/span&gt;&lt;span class="Identifier"&gt;d&lt;/span&gt;:   &lt;span class="Identifier"&gt;b8&lt;/span&gt; &lt;span class="Number"&gt;00 00 00 00 &lt;/span&gt;         &lt;span class="Identifier"&gt;mov&lt;/span&gt;    $&lt;span class="Number"&gt;0x0&lt;/span&gt;,%&lt;span class="Identifier"&gt;eax&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;     &lt;span class="Number"&gt;112&lt;/span&gt;:   &lt;span class="Identifier"&gt;c3&lt;/span&gt;                      &lt;span class="Identifier"&gt;retq&lt;/span&gt;
&lt;/pre&gt;

&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Then, in a standard un-patched Python session, let's copy the machine codes
we've just compiled from the C, and make a new function pointer that points to
them:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; ctypes
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;&lt;span class="PreProc"&gt;import&lt;/span&gt; mmap
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;PyUnicode_Type = ctypes.cast(&lt;span class="Function"&gt;id&lt;/span&gt;(&lt;span class="Function"&gt;str&lt;/span&gt;), ctypes.POINTER(PyTypeObject)).contents
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;payload = (
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;        b&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;\x8b\x4e\x18\x0f\xb6\x47\x20\xc0\xe8\x02\x83\xe0\x07\x48\x0f\xaf&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;        b&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;\xc1\x0f\xb6\x52\x30\x88\x54\x07\x30\xb8\x00\x00\x00\x00\xc3&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;)
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;buf = mmap.mmap(
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;        -&lt;span class="Number"&gt;1&lt;/span&gt;,
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;        &lt;span class="Function"&gt;len&lt;/span&gt;(payload),
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;        prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC)
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;buf.write(payload)
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;fpointer = ctypes.c_void_p.from_buffer(buf)
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;bad_boi = objobjargproc(ctypes.addressof(fpointer))
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;PyUnicode_Type.tp_as_mapping.contents.mp_ass_subscript = bad_boi
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Before we scored this righteous hack, this would happen:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; x = &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;hack the planet&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; x[&lt;span class="Number"&gt;1&lt;/span&gt;] = &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;4&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&lt;span class="Type"&gt;TypeError&lt;/span&gt;: &lt;span class="String"&gt;'&lt;/span&gt;&lt;span class="String"&gt;str&lt;/span&gt;&lt;span class="String"&gt;'&lt;/span&gt; &lt;span class="Function"&gt;object&lt;/span&gt; does &lt;span class="Statement"&gt;not&lt;/span&gt; support item assignment
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;
&lt;p&gt;but now...&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; x = &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;hack the planet&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; x[&lt;span class="Number"&gt;1&lt;/span&gt;] = &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;4&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span class="Function"&gt;print&lt;/span&gt;(x)
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;h4ck the planet&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;&lt;img alt="floppy" src="/images/hackersfloppydraw.gif" title="Zero Cool in Hackers drawing floppy disks like they are guns...precious"&gt;&lt;/p&gt;
&lt;p&gt;And so our pointless quest is over. I hope you had fun. Sometimes it is good to
remember that computers can be just for fun. 😊&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;More information about this is in the &lt;a href="https://docs.python.org/3/reference/datamodel.html"&gt;Data
Model&lt;/a&gt;. In short, there is
a defined resolution order for class hierarchies. So if &lt;code&gt;x.__dict__&lt;/code&gt; didn't
have the key &lt;code&gt;"y"&lt;/code&gt;, then we'll next look in base classes of &lt;code&gt;x&lt;/code&gt;, &amp;amp;c.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;I first seen Armin Ronacher do this on Twitter, so a lot of credit is due to
him for this great trick. Someone has uploaded his code
&lt;a href="https://gist.github.com/mahmoudimus/295200"&gt;here&lt;/a&gt; (I can't find original
tweet)&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;There is a good explanation as to why
&lt;a href="https://www.quora.com/Why-are-Python-strings-immutable/answer/Michael-Veksler"&gt;here&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/></entry><entry><title>C++ is not a superset of C</title><link href="https://mcla.ug/cpp-is-not-a-superset-of-c.html" rel="alternate"/><published>2019-09-02T00:00:00+01:00</published><updated>2019-09-02T00:00:00+01:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2019-09-02:/cpp-is-not-a-superset-of-c.html</id><summary type="html">&lt;p&gt;If you're not familiar with both languages, you might have heard people say 
that C++ is a superset of C. If you're experienced in both languages, you'll 
know that this is not true at all.&lt;/p&gt;
&lt;p&gt;Of course, C++ has many features that C does not; but there are also a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;If you're not familiar with both languages, you might have heard people say 
that C++ is a superset of C. If you're experienced in both languages, you'll 
know that this is not true at all.&lt;/p&gt;
&lt;p&gt;Of course, C++ has many features that C does not; but there are also a few 
features that only C has. And, perhaps most importantly, there is code that 
compiles in both languages but does different things.&lt;/p&gt;
&lt;p&gt;There's a lot of information about the differences between the two languages 
available, but a lot of it seems scattered. I wanted to have a go at creating a 
concise guide for the details that are often overlooked, with excerpts from the 
language standards to back these up.&lt;/p&gt;
&lt;h2&gt;Notes&lt;/h2&gt;
&lt;p&gt;This is primarily aimed at people who are familiar with at least one of C or 
C++.&lt;/p&gt;
&lt;p&gt;When I refer to C++, I mean C++11 onwards, though much of this will apply to 
earlier standards. I'll be referencing the C++17 standard&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;When I refer to C, I mean C99 onwards. I'll be referencing the C11 
standard&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;It's worth noting that a lot of compilers aren't fully compliant, or have 
extensions that aren't part of the standard. To me, this is part of what makes 
it difficult to pick apart what is standard, what is non-compliant, and what is 
implementation defined. I recommend &lt;a href="https://godbolt.org"&gt;Compiler Explorer&lt;/a&gt; if 
you want to see what other compilers might output if you are experimenting with 
any examples.&lt;/p&gt;
&lt;h2&gt;Update&lt;/h2&gt;
&lt;p&gt;I've made some updates after &lt;a href="https://news.ycombinator.com/item?id=20869451"&gt;some helpful feedback&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;fixing mistakes in the &lt;code&gt;const&lt;/code&gt; section&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;clarifying the use of implicit int in the &lt;code&gt;auto&lt;/code&gt; section&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The original post is on the &lt;a href="https://web.archive.org/web/20190903193635/https://mcla.ug/blog/cpp-is-not-a-superset-of-c.html"&gt;Internet 
Archive&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Code that compiles in both languages, but does different things in each&lt;/h1&gt;
&lt;p&gt;This is the category of differences that I think is most important. Not 
everything that C and C++ appear to share is as it seems.&lt;/p&gt;
&lt;h2&gt;const&lt;/h2&gt;
&lt;h3&gt;What can be a constant expression?&lt;/h3&gt;
&lt;p&gt;The keyword &lt;code&gt;const&lt;/code&gt; has a different semantic meaning in C++ than in C, but it's 
more subtle than I originally thought when first writing this blog post.&lt;/p&gt;
&lt;p&gt;The differences come down to what each language allows to be a &lt;em&gt;constant 
expression&lt;/em&gt;. A constant expression can be evaluated at compile time. 
Compile-time evaluation is needed for e.g. the size of a static array, as in 
the following example which will compile in C++, but whether it compiles in C 
will be implementation defined:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Type"&gt;const&lt;/span&gt; &lt;span class="Type"&gt;size_t&lt;/span&gt; buffer_size = &lt;span class="Number"&gt;5&lt;/span&gt;;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; buffer[buffer_size];
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="Comment"&gt;// int main() {&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;    &lt;span class="Comment"&gt;// ...&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;&lt;span class="Comment"&gt;// }&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;We'll need to piece together a few different pieces of the C11 standard to 
understand why this is implementation defined.&lt;/p&gt;
&lt;p&gt;C11 6.6 paragraph 6 defines an &lt;em&gt;integer constant expression&lt;/em&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An integer constant expression shall have integer type and shall only have 
operands that  are  integer  constants,  enumeration  constants,  character
constants, &lt;code&gt;sizeof&lt;/code&gt; expressions whose results are integer constants, and 
floating constants that are the immediate operands of casts. Cast operators 
in an integer constant expression shall only convert arithmetic types to 
integer types, except as part of an operand to the &lt;code&gt;sizeof&lt;/code&gt; operator.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But what is an "integer constant"? From 6.4.4, these are literal values, not 
variables, e.g. &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What this boils down to is that only expressions like &lt;code&gt;1&lt;/code&gt; or &lt;code&gt;5 + 7&lt;/code&gt; can be 
constant expressions in C. Variables can't be constant expressions. As 
expected, this example &lt;a href="https://godbolt.org/z/oMq16u"&gt;doesn't compile with 
gcc&lt;/a&gt;. But &lt;a href="https://godbolt.org/z/GgQU8X"&gt;it &lt;em&gt;does&lt;/em&gt; compile with 
Clang&lt;/a&gt;: why?&lt;/p&gt;
&lt;p&gt;The answer is one final piece of the puzzle, C11 6.6 paragraph 10:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An implementation may accept other forms of constant expressions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A portable version of the code above in C would have to use a preprocessor 
macro:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="PreProc"&gt;#define &lt;/span&gt;&lt;span class="Function"&gt;BUFFER_SIZE &lt;/span&gt;&lt;span class="PreProc"&gt;(&lt;/span&gt;&lt;span class="Number"&gt;5&lt;/span&gt;&lt;span class="PreProc"&gt;)&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; buffer[BUFFER_SIZE];
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;The keyword &lt;code&gt;const&lt;/code&gt; was created for this very purpose by Bjarne Stroustrop&lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;: 
to reduce the need for macros. C++ is much more permissive about what can be a 
constant expression, making &lt;code&gt;const&lt;/code&gt; variables more powerful.&lt;/p&gt;
&lt;p&gt;It was a surprise to me to learn that &lt;code&gt;const&lt;/code&gt; originated in what would become 
C++, and was then adopted by C. I had assumed that &lt;code&gt;const&lt;/code&gt; came from C, and C++ 
took the same concept and extended it in order to reduce the need for macros. I 
understand macros are embraced by C, but it seems a shame to deliberately 
reduce the usefulness of &lt;code&gt;const&lt;/code&gt; when standardising C.&lt;/p&gt;
&lt;h3&gt;Linkage&lt;/h3&gt;
&lt;p&gt;Another difference is that file-scope &lt;code&gt;const&lt;/code&gt; variables have internal linkage 
by default in C++. This is so that you can make a &lt;code&gt;const&lt;/code&gt; declaration in a 
header without having multiple definition errors&lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3&gt;Modifying const variables&lt;/h3&gt;
&lt;p&gt;The following code is a constraint violation in C:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id="vimCodeElement"&gt;&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Type"&gt;const&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; foo = &lt;span class="Number"&gt;1&lt;/span&gt;;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt;* bar = &amp;amp;foo;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;*bar = &lt;span class="Number"&gt;2&lt;/span&gt;;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;C11 6.5.16.1 paragraph 1 lists some constraints, one of which must be true for 
an assignment to be valid. The relevant constraint for our example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;the left operand has atomic, qualified, or unqualified pointer type, 
and (considering the type the left operand would have after lvalue 
conversion) both operands are pointers to qualified or unqualified versions 
of compatible types, and &lt;em&gt;the type pointed to by the left has all the 
qualifiers of the type pointed to by the right&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To be conformant, the compiler must generate a diagnostic if there's a 
constraint violation. This could be a warning or an error. I've found that it 
is generally a warning, meaning this &lt;a href="https://godbolt.org/z/DZdBRW"&gt;can often be compiled in 
C&lt;/a&gt;, though would give undefined behaviour&lt;sup id="fnref:5"&gt;&lt;a class="footnote-ref" href="#fn:5"&gt;5&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://godbolt.org/z/yMUvpg"&gt;This is would not compile as C++&lt;/a&gt;. I think this 
is because in C++ &lt;code&gt;const T&lt;/code&gt; is a distinct type from &lt;code&gt;T&lt;/code&gt;, and the implicit 
conversion is not allowed. In C, the &lt;code&gt;const&lt;/code&gt; is just a qualifier. I could be 
misunderstanding, however.&lt;/p&gt;
&lt;p&gt;C++17 6.7.3:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The cv-qualified or cv-unqualified versions of a type are distinct types&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Function declarations with no arguments&lt;/h2&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;func&lt;/span&gt;();
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;In C++, this declares a function that takes no arguments. But in C, this 
declares a function that could take any number of arguments of any type.&lt;/p&gt;
&lt;p&gt;From the C11 standard 6.7.6.3 paragraphs 10 and 14:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The special case of an unnamed parameter of type void as the only item in the 
list specifies that the function has no parameters.&lt;/p&gt;
&lt;p&gt;An empty list in a function declarator that is part of a definition of that 
function specifies that the function has no parameters. The empty list in a 
function declarator that is not part of a definition of that function 
specifies that no information about the number or types of the parameters is 
supplied.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So the following would be legit C:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Comment"&gt;// func.h&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;func&lt;/span&gt;();
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Comment"&gt;// func.c&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;func&lt;/span&gt;(&lt;span class="Type"&gt;int&lt;/span&gt; foo, &lt;span class="Type"&gt;int&lt;/span&gt; bar) {
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; foo + bar;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Comment"&gt;// main.c&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;func.h&amp;quot;&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;() {
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Function"&gt;func&lt;/span&gt;(&lt;span class="Number"&gt;5&lt;/span&gt;, &lt;span class="Number"&gt;6&lt;/span&gt;);
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;This would result in a compiler error in C++:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;12&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;no&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matching&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;func&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nt"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;func&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;6&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;^~~~&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="nt"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;note&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;candidate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;viable&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requires&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;were&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;provided&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;The effect of name mangling&lt;/h3&gt;
&lt;p&gt;There are some common implementation details that allow us to take this 
further. On my Linux machine using Clang, the following C compiles and links 
(though the result would of course be undefined):&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Comment"&gt;// func.h&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;func&lt;/span&gt;(&lt;span class="Type"&gt;int&lt;/span&gt; foo, &lt;span class="Type"&gt;int&lt;/span&gt; bar);
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;&lt;span class="Comment"&gt;// func.c&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;func&lt;/span&gt;(&lt;span class="Type"&gt;float&lt;/span&gt; foo, &lt;span class="Type"&gt;float&lt;/span&gt; bar) {
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Function"&gt;printf&lt;/span&gt;(&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="Special"&gt;%f&lt;/span&gt;&lt;span class="String"&gt;, &lt;/span&gt;&lt;span class="Special"&gt;%f&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;, foo, bar);
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Comment"&gt;// main.c&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;&amp;quot;func.h&amp;quot;&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;() {
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Function"&gt;func&lt;/span&gt;(&lt;span class="Number"&gt;5&lt;/span&gt;, &lt;span class="Number"&gt;6&lt;/span&gt;);
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;This does not compile in C++. C++ compilers commonly use name mangling to 
enable function overloading. They "mangle" the names of functions in order to 
encode their arguments, e.g. by appending the argument types to the function 
name. Generally, C compilers just store the function name as the symbol. We can 
see this by comparing the symbol table of &lt;code&gt;func.o&lt;/code&gt; when compiled as C and C++.&lt;/p&gt;
&lt;p&gt;As C:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;╰─λ objdump -t func.o

func.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df &lt;span class="gs"&gt;*ABS*&lt;/span&gt;  0000000000000000 foo.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .rodata.str1.1 0000000000000000 .rodata.str1.1
0000000000000000 g     F .text  000000000000002e func
0000000000000000         &lt;span class="gs"&gt;*UND*&lt;/span&gt;  0000000000000000 printf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As C++:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;╰─λ objdump -t func.o

func.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df &lt;span class="gs"&gt;*ABS*&lt;/span&gt;  0000000000000000 foo.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .rodata.str1.1 0000000000000000 .rodata.str1.1
0000000000000000 g     F .text  000000000000003b _Z4funcff
0000000000000000         &lt;span class="gs"&gt;*UND*&lt;/span&gt;  0000000000000000 printf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These implementation details are not part of the standards, but I'd be 
surprised to see an implementation that did something wildly different.&lt;/p&gt;
&lt;h2&gt;auto&lt;/h2&gt;
&lt;p&gt;I mostly include this for fun, as I think it's not as well known as it could 
be. &lt;code&gt;auto&lt;/code&gt; is used for type-inference in C++, but is also a C keyword, just one 
that I've never actually seen used.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;auto&lt;/code&gt; is used to declare something with automatic storage class. It's rarely 
seen because this is the default storage class for all variables declared 
within a block.&lt;/p&gt;
&lt;p&gt;The following C has a constraint violation, namely not specifying a type&lt;sup id="fnref:6"&gt;&lt;a class="footnote-ref" href="#fn:6"&gt;6&lt;/a&gt;&lt;/sup&gt;. 
This could error, but I've never found a compiler to give it anything but a 
warning about implicit conversion:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;() {
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    &lt;span class="Type"&gt;auto&lt;/span&gt; x = &lt;span class="String"&gt;&amp;quot;actually an int&amp;quot;&lt;/span&gt;;
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; x;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;Before C99, it was legal to have no type specifiers, and the type would be 
assumed to be &lt;code&gt;int&lt;/code&gt;. This is what happens when I compile this with 
&lt;a href="https://godbolt.org/z/ok1OSi"&gt;Clang&lt;/a&gt; and &lt;a href="https://godbolt.org/z/v5TTqP"&gt;gcc&lt;/a&gt;, 
and so we get a warning due to implicitly converting a &lt;code&gt;char&lt;/code&gt; array to &lt;code&gt;int&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In C++ this wouldn't compile, as the type of &lt;code&gt;x&lt;/code&gt; is inferred to be &lt;code&gt;const char*&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cannot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;initialize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;int&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lvalue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;const char *&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;Features C has that C++ doesn't have&lt;/h1&gt;
&lt;p&gt;Despite C being a very small language, and C++ being huge, there are a few 
features that C has that C++ does not.&lt;/p&gt;
&lt;h2&gt;Variable length arrays&lt;/h2&gt;
&lt;p&gt;VLAs allow you to define an array of automatic storage duration with variable 
length. E.g.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; &lt;span class="Function"&gt;f&lt;/span&gt;(&lt;span class="Type"&gt;int&lt;/span&gt; n) {
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;  &lt;span class="Type"&gt;int&lt;/span&gt; arr[n];
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;  &lt;span class="Comment"&gt;// ......&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;VLAs were actually made optional in the C11 standard, which makes them not very 
portable.&lt;/p&gt;
&lt;p&gt;These aren't part of C++, probably in part because the C++ standard library 
relies heavily on dynamic memory allocation to create containers like 
&lt;code&gt;std::vector&lt;/code&gt; that can be used similarly. There are reasons you might not want 
this dynamic allocation, but then perhaps you would not be using C++.&lt;/p&gt;
&lt;h2&gt;Restricted pointers&lt;/h2&gt;
&lt;p&gt;C defines a third type qualifier (in addition to &lt;code&gt;const&lt;/code&gt; and &lt;code&gt;volatile&lt;/code&gt;): 
&lt;code&gt;restrict&lt;/code&gt;&lt;sup id="fnref:7"&gt;&lt;a class="footnote-ref" href="#fn:7"&gt;7&lt;/a&gt;&lt;/sup&gt;. This is only used with pointers. Making a pointer restricted is 
telling the compiler "I will only access the underlying object via this pointer 
for the scope of this pointer". Consequently it can't be aliased. If you break 
this promise you will get undefined behaviour.&lt;/p&gt;
&lt;p&gt;This exists to aid optimisation. A classic example is &lt;code&gt;memmove&lt;/code&gt; where you can 
tell the compiler that the &lt;code&gt;src&lt;/code&gt; and &lt;code&gt;dst&lt;/code&gt; do not overlap.&lt;/p&gt;
&lt;p&gt;From C11 6.7.3 paragraph 8:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An object that is accessed through a restrict-qualified pointer has a special 
association with that pointer. This association, defined in 6.7.3.1 below, 
requires that all accesses to that object use, directly or indirectly, the 
value of that particular pointer.135)The intended use of the restrict 
qualifier (like the register storage class) is to promote optimization, and 
deleting all instances of the qualifier from all preprocessing translation 
units composing a conforming program does not change its meaning (i.e., 
observable behavior)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Restricted pointers aren't part of the C++ standard but are actually supported 
as extensions by many compilers&lt;sup id="fnref:8"&gt;&lt;a class="footnote-ref" href="#fn:8"&gt;8&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;I'm suspicious of &lt;code&gt;restrict&lt;/code&gt;. It seems like playing with fire, and anecdotally 
it seems common to run into compiler optimisation bugs when using it because 
it's exercised so little&lt;sup id="fnref:9"&gt;&lt;a class="footnote-ref" href="#fn:9"&gt;9&lt;/a&gt;&lt;/sup&gt;. But it's easy to be suspicious of something I've 
never actually used.&lt;/p&gt;
&lt;h2&gt;Designated initialisers&lt;/h2&gt;
&lt;p&gt;C99 brought in an incredibly useful way to initialise structs, and I do not 
understand why it has not been adopted by C++.&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement'&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Type"&gt;typedef&lt;/span&gt; &lt;span class="Type"&gt;struct&lt;/span&gt; {
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;    &lt;span class="Type"&gt;float&lt;/span&gt; red;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;    &lt;span class="Type"&gt;float&lt;/span&gt; green;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;    &lt;span class="Type"&gt;float&lt;/span&gt; blue;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;} Colour;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;() {
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    Colour c = { .red = &lt;span class="Number"&gt;0.1&lt;/span&gt;, .green = &lt;span class="Number"&gt;0.5&lt;/span&gt;, .blue = &lt;span class="Number"&gt;0.9&lt;/span&gt; };
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;In C++ you would have to initialise like this: &lt;code&gt;Colour c = { 0.1, 0.5, 0.9 };&lt;/code&gt; 
which is harder to read and not robust to changes in the definition of 
&lt;code&gt;Colour&lt;/code&gt;. You could instead define a constructor but why should we have to do 
this for a simple aggregate type? I hear designated initialisers are now coming 
in C++20. It only took 21 years...&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;The closest working draft I could find for free online: 
&lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf"&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf"&gt;http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a href="http://www.stroustrup.com/sibling_rivalry.pdf"&gt;Sibling Rivalry, 2002, Bjarne 
Stroustrup&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;C++11 standard appendix C.1.2&amp;#160;&lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;From C11 6.7.3 paragraph 6:  If an attempt is made to modify an object 
defined with a const-qualified type through use of an lvalue with 
non-const-qualified type, the behavior is undefined.&amp;#160;&lt;a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 5 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;C11 6.7.2&amp;#160;&lt;a class="footnote-backref" href="#fnref:6" title="Jump back to footnote 6 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:7"&gt;
&lt;p&gt;C11 also defines type qualifier &lt;code&gt;_Atomic&lt;/code&gt; but I didn't include it here 
for reasons of: conciseness; it's ugly (it's a shame it couldn't be &lt;code&gt;atomic&lt;/code&gt;, 
too much existing code uses that); I don't know how common it is as a lot of 
people still use C99; C++ also has atomic types as part of the STL so it wasn't 
an interesting example.&amp;#160;&lt;a class="footnote-backref" href="#fnref:7" title="Jump back to footnote 7 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:8"&gt;
&lt;p&gt;&lt;a href="https://gcc.gnu.org/onlinedocs/gcc-6.4.0/gcc/Restricted-Pointers.html"&gt;https://gcc.gnu.org/onlinedocs/gcc-6.4.0/gcc/Restricted-Pointers.html&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:8" title="Jump back to footnote 8 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:9"&gt;
&lt;p&gt;&lt;a href="https://software.intel.com/en-us/forums/intel-c-compiler/topic/474141"&gt;https://software.intel.com/en-us/forums/intel-c-compiler/topic/474141&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:9" title="Jump back to footnote 9 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/></entry><entry><title>C++20 concepts are not like Rust traits</title><link href="https://mcla.ug/cpp20-concepts-are-not-like-rust-traits.html" rel="alternate"/><published>2019-08-21T00:00:00+01:00</published><updated>2019-08-21T00:00:00+01:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2019-08-21:/cpp20-concepts-are-not-like-rust-traits.html</id><summary type="html">&lt;p&gt;At writing, &lt;a href="https://en.wikipedia.org/w/index.php?title=Rust_(programming_language)&amp;amp;oldid=910954500"&gt;Rust's 
Wikipedia&lt;/a&gt; 
currently says the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Functions can be given generic parameters, which usually require the generic 
type to implement a certain trait or traits. Within such a function, the 
generic value can only be used through those traits. This means that a generic 
function can be type-checked …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;At writing, &lt;a href="https://en.wikipedia.org/w/index.php?title=Rust_(programming_language)&amp;amp;oldid=910954500"&gt;Rust's 
Wikipedia&lt;/a&gt; 
currently says the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Functions can be given generic parameters, which usually require the generic 
type to implement a certain trait or traits. Within such a function, the 
generic value can only be used through those traits. This means that a generic 
function can be type-checked as soon as it is defined. This is in contrast to 
C++ templates, which are fundamentally duck typed and cannot be checked until 
instantiated with concrete types. C++ concepts address the same issue and are 
expected to be part of C++20 (2020).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But C++ concepts (as currently proposed) are very different from Rust traits, and do not allow for the parameterised function to be type-checked only once.&lt;/p&gt;
&lt;p&gt;Rust traits are implemented explicitly, whereas C++ concept constraints are 
implicitly met. This means that concept-constrained templates can legally 
invoke behaviour not defined by the concept. So, the following code compiles in 
g++ v9.2 with flags &lt;code&gt;--std=c++2a -fconcepts&lt;/code&gt;:&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;&lt;span class="Type"&gt;template&lt;/span&gt;&amp;lt;&lt;span class="Type"&gt;typename&lt;/span&gt; T&amp;gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;concept &lt;span class="Type"&gt;bool&lt;/span&gt; Stringable = &lt;span class="Function"&gt;requires&lt;/span&gt;(T a) {
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;    {a.&lt;span class="Function"&gt;stringify&lt;/span&gt;()} -&amp;gt; &lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Type"&gt;string&lt;/span&gt;;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;};
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;&lt;span class="Type"&gt;class&lt;/span&gt; Cat {
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt; &lt;span class="Statement"&gt;public&lt;/span&gt;:
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;    &lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Type"&gt;string&lt;/span&gt; &lt;span class="Function"&gt;stringify&lt;/span&gt;() {
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;        &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;meow&amp;quot;&lt;/span&gt;;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;    }
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;    &lt;span class="Type"&gt;void&lt;/span&gt; &lt;span class="Function"&gt;pet&lt;/span&gt;() {
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;    }
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;};
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;&lt;span class="Type"&gt;template&lt;/span&gt;&amp;lt;Stringable T&amp;gt;
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;&lt;span class="Type"&gt;void&lt;/span&gt; &lt;span class="Function"&gt;f&lt;/span&gt;(T a) {
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;    a.&lt;span class="Function"&gt;pet&lt;/span&gt;();
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;}
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;&lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;() {
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;    &lt;span class="Function"&gt;f&lt;/span&gt;(&lt;span class="Function"&gt;Cat&lt;/span&gt;());
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;;
&lt;span id="L26" class="LineNr"&gt;26 &lt;/span&gt;}
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;The Rust equivalent would not compile:&lt;/p&gt;
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Keyword"&gt;trait&lt;/span&gt; &lt;span 
class="Identifier"&gt;Stringable&lt;/span&gt; {
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;    &lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;stringify&lt;/span&gt;() &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Type"&gt;String&lt;/span&gt;;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;}
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;&lt;span class="Keyword"&gt;struct&lt;/span&gt; &lt;span class="Identifier"&gt;Cat&lt;/span&gt; {
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;}
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;&lt;span class="Keyword"&gt;impl&lt;/span&gt; Cat {
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;pet&lt;/span&gt;() {}
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;}
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;&lt;span class="Keyword"&gt;impl&lt;/span&gt; Stringable &lt;span class="Statement"&gt;for&lt;/span&gt; Cat {
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;    &lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;stringify&lt;/span&gt;() &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Type"&gt;String&lt;/span&gt; {
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;        &lt;span class="String"&gt;&amp;quot;meow&amp;quot;&lt;/span&gt;.&lt;span class="Function"&gt;to_string&lt;/span&gt;()
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;    }
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;}
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;&lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;f&lt;/span&gt;&lt;span class="Statement"&gt;&amp;lt;&lt;/span&gt;T: Stringable&lt;span class="Statement"&gt;&amp;gt;&lt;/span&gt;(a: T) {
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;    a.&lt;span class="Function"&gt;pet&lt;/span&gt;();  &lt;span class="Comment"&gt;// error[E0599]: no method named `pet` found for type `T` in the current scope&lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;}
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;&lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;main&lt;/span&gt;() {
&lt;span id="L23" class="LineNr"&gt;23 &lt;/span&gt;    &lt;span class="Keyword"&gt;let&lt;/span&gt; cat &lt;span class="Statement"&gt;=&lt;/span&gt; Cat{};
&lt;span id="L24" class="LineNr"&gt;24 &lt;/span&gt;    &lt;span class="Function"&gt;f&lt;/span&gt;(cat);
&lt;span id="L25" class="LineNr"&gt;25 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

&lt;p&gt;C++ concept-constrained templates are still only type checked when concrete 
instantiation is attempted &amp;ndash; they just give better, sooner error messages 
for types that don't comply with the constraint, rather than the long stream of 
nonsense that failed template instantiations output in C++ without concepts.&lt;/p&gt;
&lt;p&gt;I think it's quite common for people to think that concepts are the same as 
traits. They look similar syntactically, and also the realities of them aren't 
well known because they aren't yet in a standard. I hope this can clarify 
things for anyone curious, and help anyone adjust expectations before the C++20 
standard is released.&lt;/p&gt;
&lt;h1&gt;Rust traits comparisons with other language constructs&lt;/h1&gt;
&lt;p&gt;Although Rust traits are very different from C++20 concepts, they have 
similarities to a lot of other language constructs for polymorphism:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Haskell typeclasses: Rust traits are based on these, but Rust does not have 
  higher kinded types&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;, and Rust enforces global uniqueness on trait 
  implementations&lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;4&lt;/a&gt;&lt;/sup&gt;. This means that there is at most one implementation 
  of a trait for any given type. This is not enforced in Haskell, but it is 
  discouraged to take advantage of this.&lt;sup id="fnref:5"&gt;&lt;a class="footnote-ref" href="#fn:5"&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Java interfaces: when Rust traits are used dynamically, they are analogous to 
  Java interfaces, except without the &lt;code&gt;extend&lt;/code&gt; functionality available in 
  Java.&lt;sup id="fnref:6"&gt;&lt;a class="footnote-ref" href="#fn:6"&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://godbolt.org/z/qA3hlL"&gt;https://godbolt.org/z/qA3hlL&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://github.com/rust-lang/rfcs/issues/324"&gt;https://github.com/rust-lang/rfcs/issues/324&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;a href="http://aturon.github.io/tech/2017/02/06/specialization-and-coherence/"&gt;http://aturon.github.io/tech/2017/02/06/specialization-and-coherence/&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://github.com/ixrec/rust-orphan-rules/blob/master/README.md"&gt;https://github.com/ixrec/rust-orphan-rules/blob/master/README.md&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;&lt;a href="http://blog.ezyang.com/2014/07/type-classes-confluence-coherence-global-uniqueness/"&gt;http://blog.ezyang.com/2014/07/type-classes-confluence-coherence-global-uniqueness/&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 5 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;&lt;a href="https://stevedonovan.github.io/rust-gentle-intro/object-orientation.html"&gt;https://stevedonovan.github.io/rust-gentle-intro/object-orientation.html&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:6" title="Jump back to footnote 6 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/></entry><entry><title>Rust: a future for real-time and safety-critical software without C or C++</title><link href="https://mcla.ug/rust-a-future-for-real-time-and-safety-critical-software.html" rel="alternate"/><published>2019-08-20T00:00:00+01:00</published><updated>2019-08-20T00:00:00+01:00</updated><author><name>Hannah McLaughlin</name></author><id>tag:mcla.ug,2019-08-20:/rust-a-future-for-real-time-and-safety-critical-software.html</id><summary type="html">&lt;h1&gt;Overview&lt;/h1&gt;
&lt;p&gt;Rust is a fairly new programming language that I'm really excited about. I gave 
a talk about it to my coworkers, primarily aimed at C++ programmers. This is 
that talk translated to a blog post. I hope you will be excited about Rust too 
by the end of this …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Overview&lt;/h1&gt;
&lt;p&gt;Rust is a fairly new programming language that I'm really excited about. I gave 
a talk about it to my coworkers, primarily aimed at C++ programmers. This is 
that talk translated to a blog post. I hope you will be excited about Rust too 
by the end of this blog post!&lt;/p&gt;
&lt;p&gt;A quick overview: Rust is syntactically similar to C++, but semantically very 
different. It's heavily influenced by functional programming languages like 
Haskell and OCaml. It's statically typed, with full type inference, rather than 
the partial type inference that C++ has. It's as fast as C and C++ while making 
guarantees about memory safety that are impossible to make in those languages.&lt;/p&gt;
&lt;h1&gt;house[-1]&lt;/h1&gt;
&lt;p&gt;Before we look at Rust in any more detail, I want you to imagine yourself in a 
scenario. Imagine that you are a builder setting up the gas supply in a new house. Your 
boss tells you to connect the gas pipe in the basement to the gas main on the 
pavement. You go downstairs, and find that there's a glitch: this house doesn't 
have a basement!&lt;/p&gt;
&lt;p&gt;So, what do you do? Perhaps you do nothing, or perhaps you decide to 
whimsically interpret your instruction by attaching the gas main to some other 
nearby fixture, like the air conditioning intake for the office next door. 
Either way, suppose you report back to your boss that you're done.&lt;/p&gt;
&lt;p&gt;&lt;img alt="KWABOOM" src="/images/rust-talk/explosion.png" title="A cartoon explosion, in red and yellow, with some shrapnel"&gt;&lt;/p&gt;
&lt;p&gt;KWABOOM! When the dust settles from the explosion, you would be guilty of 
criminal negligence.[^1]&lt;/p&gt;
&lt;p&gt;Yet this is exactly what happens in some programming languages. In C you could 
have an array, or in C++ you could have a vector, ask for the -1 index, and 
anything could happen. The result could be different any time you run the 
program, and you might not realise that something is wrong. This is called 
undefined behaviour, and the possibility of it can't be eliminated entirely, 
because low-level hardware operations are inherently unsafe, but it's something 
that is protected against in many languages, just not C and C++.&lt;/p&gt;
&lt;p&gt;The lack of memory safety guarantees from these languages, and the ease with 
which undefined behaviour can be invoked, is terrifying when you think of how 
much of the world runs on software. Heartbleed, the famous SSL vulnerability, 
was due to this lack of memory safety; Stagefright, a famous Android 
vulnerability,  was due to undefined behaviour from signed integer overflow in 
C++.&lt;/p&gt;
&lt;html&gt;
&lt;div class=info_box&gt;
Memory safety is crucial to both the correctness and reliability of a program.
&lt;/div&gt;
&lt;html&gt;

Vulnerabilities aren't the only concern. Memory safety is crucial to both the 
correctness and reliability of a program. No one wants their program to crash 
out of nowhere, no matter how minor the application: reliability matters. As 
for correctness, I have a friend who used to work on rocket flight simulation 
software and they found passing in the same initialisation data but with a 
different filename gave you a different result, because some uninitialised 
memory was being read, it happened to read the program argument's memory, and 
so the simulation was seeded with garbage values based on the filename. 
Arguably their entire business was a lie.

# So why not use memory safe languages like Python or Java?
Languages like Python and Java use garbage collection to automatically protect 
us from bad memory accesses, like

* use-after-frees (when you access memory that has been deallocated)

* double frees (when you release memory that's already been released, 
  potentially corrupting the heap)

* memory leaks (when memory that isn't being used is never released. This isn't 
  necessarily dangerous but can cause your system to crash and destroy 
  performance.)

Languages like Python and Java protect from these situations automatically. A 
garbage collector will run as part of the JVM or the Python interpreter, and 
periodically check memory to find unused objects, releasing their associated resources and
memory.

But it does this at great cost. Garbage collection is slow, it uses a lot of 
memory, and crucially it means that at any point &amp;ndash; you don't know when &amp;ndash; 
the program will halt &amp;ndash; for how long, you don't know &amp;ndash; to clean up the 
garbage.

&lt;html&gt;
&lt;div class=info_box&gt;
**Python and Java**&lt;br&gt;memory safe at the cost of speed and determinism
&lt;br&gt;&lt;br&gt;
**C and C++**&lt;br&gt;fast and deterministic at the cost of memory safety
&lt;/div&gt;
&lt;html&gt;

This lack of predictability makes it impossible to use Python or Java for
real-time applications, where you must guarantee that operations will complete
within a specified period of time. It's not about being as fast as possible,
it's about guaranteeing you will be fast enough every single time.

So of course, there are social reasons why C and C++ are popular: it's what 
people know and they've been around a long time. But they are also popular because 
they are fast and deterministic.
Unfortunately, this comes at the cost of memory safety. Even worse, many
real-time applications are also safety critical, like control software in cars 
and surgical robots. As a result, safety critical applications often use these 
dangerous languages.

For a long time, this has been a fundamental trade-off. You either get speed
and predictability, or you get memory safety.

Rust completely overturns this, which is what makes it so exciting and notable.

# What this blog post will cover
These are the questions I hope to answer in this post:

* What are Rust's design goals?

* How does Rust achieve memory safety?

* What does polymorphism look like in Rust?

* What is Rust tooling like?

# What are Rust's design goals?
* Concurrency without data races

    * Concurrency happens whenever different parts of your program might 
      execute at different times or out of order.

    * We'll discuss data races more later, but they're a common hazard when 
      writing concurrent programs, as many of you will know.

* Abstraction without overhead

    * This just means that the conveniences and expressive power that the 
      language provides don't come at a run time cost, it doesn't slow your 
      program down to use them.

* Memory safety without garbage collection

    * We've just talked about what these two terms mean. Let's have a look at 
      how Rust achieves this previously contradictory pairing.

# Memory safety without garbage collection
How Rust achieves memory safety is simultaneously really simple and really
complex.

It's simple because all it involves is enforcing a few simple rules, which are
really easy to understand.

In Rust, all objects have an _owner_, tracked by the compiler. There can only 
be one owner at a time, which is very different to how things work in most 
other programming languages. It ensures that there is exactly one binding to 
any given resource.
This alone would be very restrictive, so of course we can also give out 
references according to strict rules. Taking a reference is often called 
"borrowing" in Rust and I'm going to use that language here.

The rules for borrowing are:

&gt; Any borrow must last for a scope no greater than that of the owner.
&gt;
&gt; You may have one or the other of these two kinds of borrows, but not both at 
&gt; the same time:

&gt;    one or more immutable references to a resource
&gt;    OR
&gt;    exactly one mutable reference.

The first rule eliminates use-after-frees. The second rule eliminates data
races. A data race happens when:

* two or more pointers access the same memory location at the same time

* at least one of them is writing

* and the operations aren't synchronised.

The memory is left in an unknown state.

We didn't have a heap when I worked as an embedded engineer, and we had a 
hardware trap for null pointer derefs. So a lot of common memory safety issues 
weren't a major concern. Data races were the main type of bug I was really 
scared of. Races can be difficult to detect until you make a seemingly insignificant 
change to the code, or there's a slight change in the external conditions, and 
suddenly the winner of the race changes. A data race caused multiple deaths
in Therac-25 when patients were given lethal doses of radiation during cancer 
treatment.

&lt;html&gt;
&lt;div class=info_box&gt;
Rust's key innovation is enforcing its memory safety rules at compile time.
&lt;/div&gt;
&lt;html&gt;

As I said, these rules are simple and shouldn't be surprising for anyone who's 
ever had to deal with the possibility of data races before
&amp;ndash; but when I said that they are also complex, I meant it is incredibly smart 
that Rust is able to enforce these rules at compile time. This is Rust's key innovation.

There are some memory-safety checks that have to be runtime &amp;ndash; like array
bounds checking. But if you are writing idiomatic Rust you'll almost never need
these &amp;ndash; you wouldn't usually be directly indexing an array. Instead you'd be
using higher-order functions like fold, map and filter &amp;ndash; you will be familiar
with this type of function if you've written Haskell/Scala or even Python.

## unsafe Rust
I mentioned earlier that the possibility of undefined behaviour isn't something 
that can be eliminated entirely, due to the inherently unsafe nature of low 
level operations. Rust allows you to do such operations within specific unsafe 
blocks. I believe C# and Ada have similar constructs for disabling certain 
safety checks. You'll often need this in Rust when doing embedded programming, 
or low level systems programming. The ability to isolate the potentially unsafe 
parts of your code is incredibly useful &amp;ndash; those parts will be subject to a 
higher level of scrutiny, and if you have a bug that looks like a memory 
problem, those will be the only place that can be causing it, rather than 
absolutely anywhere in your code.

The unsafe block doesn't disable the borrow checker, which is the part of the 
compiler that enforces the borrowing rules we just talked about
&amp;ndash; it just allows you to dereference raw pointers, or access/modify mutable 
static variables. The benefits of the ownership system are still there.

# Revisiting ownership
Speaking of the ownership system, I want to compare it with ownership in C++.

Ownership semantics in C++ changed the language drastically when C++11 came 
out. But the language paid such a high price for backwards compatibility. 
Ownership, to me, feels unnaturally tacked onto C++. The previously simple value
taxonomy was butchered by it[^2]. In many ways it was a great achievement to 
massively modernise such a widely used language, but Rust shows us what a 
language can look like when ownership is a core design concept from the 
beginning.

&lt;html&gt;
&lt;div class=info_box&gt;
C++ smart pointers are just a library on top of an outdated system, and as such 
can be misused and abused in ways that Rust just does not allow.&lt;/div&gt;
&lt;html&gt;

C++'s type system does not model object lifetime at all. You can't check for
use-after-frees at compile time. Smart pointers are just a library on top of an 
outdated system, and as such can be misused and abused in ways that Rust just 
does not allow.

Let's take a look at some (simplified) C++ code I wrote at work, where this 
misuse occurs. Then we can look at a Rust equivalent, which (rightly) doesn't compile.

# Abusing smart pointers in C++
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;&amp;lt;functional&amp;gt;&lt;/span&gt;
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;&amp;lt;memory&amp;gt;&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;&lt;span class="PreProc"&gt;#include &lt;/span&gt;&lt;span class="String"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;&lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Type"&gt;vector&lt;/span&gt;&amp;lt;DataValueCheck&amp;gt; &lt;span 
class="Function"&gt;createChecksFromStrings&lt;/span&gt;(
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;        &lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Type"&gt;unique_ptr&lt;/span&gt;&amp;lt;Data&amp;gt; data,
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;        &lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Type"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Type"&gt;string&lt;/span&gt;&amp;gt; dataCheckStrs) {
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    &lt;span class="Type"&gt;auto&lt;/span&gt; createCheck = [&amp;amp;](&lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span 
class="Type"&gt;string&lt;/span&gt; checkStr) {
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;        &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Function"&gt;DataValueCheck&lt;/span&gt;(checkStr, &lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Function"&gt;move&lt;/span&gt;(data));
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;    };
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;    &lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Type"&gt;vector&lt;/span&gt;&amp;lt;DataValueCheck&amp;gt; checks;
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;    &lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Function"&gt;transform&lt;/span&gt;(
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;            dataCheckStrs.&lt;span class="Function"&gt;begin&lt;/span&gt;(),
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;            dataCheckStrs.&lt;span class="Function"&gt;end&lt;/span&gt;(),
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;            &lt;span class="Constant"&gt;std&lt;/span&gt;::&lt;span class="Function"&gt;back_inserter&lt;/span&gt;(checks),
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;            createCheck);
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; checks;
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;
The idea of this code is that we take some strings defining some checks to be
performed on some data, e.g. is a value within a particular range. We
then create a vector of check objects by parsing these strings.

First, we create a lambda that captures by reference, hence the ampersand. The
unique pointer to the data is moved in this lambda, which was a mistake.

We then fill our vector with checks constructed from moved data. The problem is
that only the first move will be successful. Unique pointers are move-only.
So after the first loop in `std::transform`, probably the unique pointer is
nulled (the standard only specifies that it will be left in a valid but unknown
state, but in my experience with Clang it's generally nulled).

Using that null pointer later results in undefined behaviour! In my case, I got
a segmentation fault, which is what will happen on a nullptr deref on most
hosted systems, because the zero memory page is usually reserved. But this
behaviour certainly isn't guaranteed. A bug like this could in theory lie dormant for a while, and then
your application would crash out of nowhere.

The use of the lambda here is a large part of what makes this dangerous. The
compiler just sees a function pointer at the call-site. It can't inspect the
lambda the way it might a standard function.

For context on understanding how this bug came about, originally, we were
using a shared_ptr to store the data, which would have made
this code fine. We wrongly thought we could store it in a unique_ptr instead,
and this bug came about when we made the change. It went unnoticed in part
because the compiler didn't complain.

I'm glad this happened because it means I can show you a real example of a C++ 
memory
safety bug that went unnoticed by both me and my code reviewer, until it later 
showed up in a test[^3]. It doesn't matter if you're an experienced programmer 
&amp;ndash;
these bugs happen! And the compiler can't save you. We must demand better
tools, for our sanity and for public safety. This is an ethical concern.

With that in mind, let's look at a Rust version.

# In Rust, that bad move is not allowed
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Keyword"&gt;pub&lt;/span&gt; &lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;create_checks_from_strings&lt;/span&gt;(
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;        data: &lt;span class="Type"&gt;Box&lt;/span&gt;&lt;span class="Statement"&gt;&amp;lt;&lt;/span&gt;Data&lt;span class="Statement"&gt;&amp;gt;&lt;/span&gt;,
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;        data_check_strs: &lt;span class="Type"&gt;Vec&lt;/span&gt;&lt;span class="Statement"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Type"&gt;String&lt;/span&gt;&lt;span class="Statement"&gt;&amp;gt;&lt;/span&gt;)
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;    &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Type"&gt;Vec&lt;/span&gt;&lt;span class="Statement"&gt;&amp;lt;&lt;/span&gt;DataValueCheck&lt;span class="Statement"&gt;&amp;gt;&lt;/span&gt;
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;{
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;    &lt;span class="Keyword"&gt;let&lt;/span&gt; create_check &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="Statement"&gt;|&lt;/span&gt;check_str: &lt;span class="Type"&gt;&amp;amp;&lt;/span&gt;&lt;span class="Type"&gt;String&lt;/span&gt;&lt;span class="Statement"&gt;|&lt;/span&gt; &lt;span class="PreProc"&gt;DataValueCheck&lt;/span&gt;&lt;span class="Special"&gt;::&lt;/span&gt;&lt;span class="Function"&gt;new&lt;/span&gt;(check_str, data);
&lt;span id="L7" class="LineNr"&gt;7 &lt;/span&gt;    data_check_strs.&lt;span class="Function"&gt;iter&lt;/span&gt;().&lt;span class="Function"&gt;map&lt;/span&gt;(create_check).&lt;span class="Function"&gt;collect&lt;/span&gt;()
&lt;span id="L8" class="LineNr"&gt;8 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;
This is our first look at some Rust code. Now is a good time for me to mention 
that variables are immutable by default. For something to be modifiable, we 
need to use the `mut` keyword &amp;ndash; kind of like the opposite of `const` in C 
and C++.

The Box type just means that we've allocated on the heap. I chose it here 
because unique_ptrs are also heap allocated. We don't need anything else to be 
analogous with unique_ptr because of Rust's rule about each object having only 
one owner at a time.

We're then creating a closure, and then using the higher order function `map` 
to apply it to the strings. It's very similar to the C++ version, but less 
verbose.

But! This doesn't compile, and here's the error message.
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;error[E0525]: expected a closure that 
implements the `&lt;span class="Type"&gt;FnMut&lt;/span&gt;` &lt;span 
class="Keyword"&gt;trait&lt;/span&gt;, but this closure only implements `&lt;span 
class="Type"&gt;FnOnce&lt;/span&gt;`
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;  &lt;span class="Statement"&gt;-&lt;/span&gt;&lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; bad_move.rs:&lt;span class="Number"&gt;1&lt;/span&gt;:&lt;span class="Number"&gt;8&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;   &lt;span class="Statement"&gt;|&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt; &lt;span class="Number"&gt;6&lt;/span&gt; &lt;span class="Statement"&gt;|&lt;/span&gt;     &lt;span class="Keyword"&gt;let&lt;/span&gt; create_check &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="Statement"&gt;|&lt;/span&gt;check_str: &lt;span class="Type"&gt;&amp;amp;&lt;/span&gt;&lt;span class="Type"&gt;String&lt;/span&gt;&lt;span class="Statement"&gt;|&lt;/span&gt; &lt;span class="PreProc"&gt;DataValueCheck&lt;/span&gt;&lt;span class="Special"&gt;::&lt;/span&gt;&lt;span class="Function"&gt;new&lt;/span&gt;(check_str, data);
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;   &lt;span class="Statement"&gt;|&lt;/span&gt;                        &lt;span class="Statement"&gt;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----^&lt;/span&gt;
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;   &lt;span class="Statement"&gt;|&lt;/span&gt;                        &lt;span class="Statement"&gt;|&lt;/span&gt;                                                     &lt;span class="Statement"&gt;|&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;   &lt;span class="Statement"&gt;|&lt;/span&gt;                        &lt;span class="Statement"&gt;|&lt;/span&gt;                                 closure is `&lt;span class="Type"&gt;FnOnce&lt;/span&gt;` because it moves
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;   &lt;span class="Statement"&gt;|&lt;/span&gt;                        &lt;span class="Statement"&gt;|&lt;/span&gt;                                 the variable `data` out of its environment
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;   &lt;span class="Statement"&gt;|&lt;/span&gt;                        this closure implements `&lt;span class="Type"&gt;FnOnce&lt;/span&gt;`, not `&lt;span class="Type"&gt;FnMut&lt;/span&gt;`
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt; &lt;span class="Number"&gt;7&lt;/span&gt; &lt;span class="Statement"&gt;|&lt;/span&gt;     data_check_strs.&lt;span class="Function"&gt;iter&lt;/span&gt;().&lt;span class="Function"&gt;map&lt;/span&gt;(create_check).&lt;span class="Function"&gt;collect&lt;/span&gt;()
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;   &lt;span class="Statement"&gt;|&lt;/span&gt;                            &lt;span class="Statement"&gt;---&lt;/span&gt; the requirement to implement `&lt;span class="Type"&gt;FnMut&lt;/span&gt;` derives from here
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;error: aborting due to previous error
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;For more information about this error, try `rustc &lt;span class="Statement"&gt;--&lt;/span&gt;explain E0525`.
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

One really great thing about the Rust community is there's a really strong 
focus on making sure there's lots of resources for people to learn, and on 
having readable error messages. You can even ask the compiler for more 
information about the error
message, and it will show you a minimal example with explanations.

When we create our closure, the data variable is moved inside it because of the
one owner rule. The compiler 
then infers that the closure can only be run once: further calls are illegal as 
we no longer own the variable. Then, the function `map` requires a callable 
that can be called repeatedly and mutate state, so the compilation fails.

I think this snippet shows how powerful the type system is in Rust compared to 
C++, and how different it is to program in a language where the compiler tracks 
object lifetime.

You'll notice that the error message here mentions traits: "expected a closure 
that implements FnMut trait", for example. Traits are a language feature that 
tell the compiler what functionality a type must provide. Traits are Rust's 
mechanism for polymorphism.

# Polymorphism
In C++ there's a lot of different ways of doing polymorphism, which I think 
contributes to how bloated the language can feel. There's templates,
function &amp; operator overloading for static polymorphism, and subtyping for 
dynamic polymorphism. These can have major downsides: subtyping can lead to 
very high coupling, and templates can be unpleasant to use due to their lack of 
parameterisation.

In Rust, traits provide a unified way of specifying both static and dynamic 
interfaces. They are Rust's sole notion of interface. They only support the
"implements" relationship, not the "extends" relationship. This encourages 
designs that are based on composition, not implementation inheritance, leading to less 
coupling.

Let's have a look at an example.
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Keyword"&gt;trait&lt;/span&gt; &lt;span class="Identifier"&gt;Rateable&lt;/span&gt; {
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;    &lt;span class="Special"&gt;/// Rate fluff out of 10&lt;/span&gt;
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;    &lt;span class="Special"&gt;/// Ratings above 10 for exceptionally soft bois&lt;/span&gt;
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;    &lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;fluff_rating&lt;/span&gt;(&lt;span class="Type"&gt;&amp;amp;&lt;/span&gt;&lt;span class="Constant"&gt;self&lt;/span&gt;) &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Type"&gt;f32&lt;/span&gt;;
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;}
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;&lt;span class="Keyword"&gt;struct&lt;/span&gt; &lt;span class="Identifier"&gt;Alpaca&lt;/span&gt; {
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;    days_since_shearing: &lt;span class="Type"&gt;f32&lt;/span&gt;,
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    age: &lt;span class="Type"&gt;f32&lt;/span&gt;
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;}
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;&lt;span class="Keyword"&gt;impl&lt;/span&gt; Rateable &lt;span class="Statement"&gt;for&lt;/span&gt; Alpaca {
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;    &lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;fluff_rating&lt;/span&gt;(&lt;span class="Type"&gt;&amp;amp;&lt;/span&gt;&lt;span class="Constant"&gt;self&lt;/span&gt;) &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Type"&gt;f32&lt;/span&gt; {
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;        &lt;span class="Number"&gt;10.0&lt;/span&gt; &lt;span class="Statement"&gt;*&lt;/span&gt; &lt;span class="Number"&gt;365.0&lt;/span&gt; &lt;span class="Statement"&gt;/&lt;/span&gt; &lt;span class="Constant"&gt;self&lt;/span&gt;.days_since_shearing
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;    }
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

There's nothing complicated going on here, I decided a simple but fun example 
was best. First, we're defining a trait called `Rateable`. For a type to be 
`Rateable`, it has to implement a function called `fluff_rating` that returns a 
float.

Then we define a type called `Alpaca` and implement this interface for it. We 
could do the same for another type, say `Cat`!
&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt; 1 &lt;/span&gt;&lt;span class="Keyword"&gt;enum&lt;/span&gt; &lt;span class="Identifier"&gt;Coat&lt;/span&gt; {
&lt;span id="L2" class="LineNr"&gt; 2 &lt;/span&gt;    Hairless,
&lt;span id="L3" class="LineNr"&gt; 3 &lt;/span&gt;    Short,
&lt;span id="L4" class="LineNr"&gt; 4 &lt;/span&gt;    Medium,
&lt;span id="L5" class="LineNr"&gt; 5 &lt;/span&gt;    Long
&lt;span id="L6" class="LineNr"&gt; 6 &lt;/span&gt;}
&lt;span id="L7" class="LineNr"&gt; 7 &lt;/span&gt;
&lt;span id="L8" class="LineNr"&gt; 8 &lt;/span&gt;&lt;span class="Keyword"&gt;struct&lt;/span&gt; &lt;span class="Identifier"&gt;Cat&lt;/span&gt; {
&lt;span id="L9" class="LineNr"&gt; 9 &lt;/span&gt;    coat: Coat,
&lt;span id="L10" class="LineNr"&gt;10 &lt;/span&gt;    age: &lt;span class="Type"&gt;f32&lt;/span&gt;
&lt;span id="L11" class="LineNr"&gt;11 &lt;/span&gt;}
&lt;span id="L12" class="LineNr"&gt;12 &lt;/span&gt;
&lt;span id="L13" class="LineNr"&gt;13 &lt;/span&gt;&lt;span class="Keyword"&gt;impl&lt;/span&gt; Rateable &lt;span class="Statement"&gt;for&lt;/span&gt; Cat {
&lt;span id="L14" class="LineNr"&gt;14 &lt;/span&gt;    &lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;fluff_rating&lt;/span&gt;(&lt;span class="Type"&gt;&amp;amp;&lt;/span&gt;&lt;span class="Constant"&gt;self&lt;/span&gt;) &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Type"&gt;f32&lt;/span&gt; {
&lt;span id="L15" class="LineNr"&gt;15 &lt;/span&gt;        &lt;span class="Statement"&gt;match&lt;/span&gt; &lt;span class="Constant"&gt;self&lt;/span&gt;.coat {
&lt;span id="L16" class="LineNr"&gt;16 &lt;/span&gt;            &lt;span class="PreProc"&gt;Coat&lt;/span&gt;&lt;span class="Special"&gt;::&lt;/span&gt;Hairless &lt;span class="Statement"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="Number"&gt;0.0&lt;/span&gt;,
&lt;span id="L17" class="LineNr"&gt;17 &lt;/span&gt;            &lt;span class="PreProc"&gt;Coat&lt;/span&gt;&lt;span class="Special"&gt;::&lt;/span&gt;Short &lt;span class="Statement"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="Number"&gt;5.0&lt;/span&gt;,
&lt;span id="L18" class="LineNr"&gt;18 &lt;/span&gt;            &lt;span class="PreProc"&gt;Coat&lt;/span&gt;&lt;span class="Special"&gt;::&lt;/span&gt;Medium &lt;span class="Statement"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="Number"&gt;7.5&lt;/span&gt;,
&lt;span id="L19" class="LineNr"&gt;19 &lt;/span&gt;            &lt;span class="PreProc"&gt;Coat&lt;/span&gt;&lt;span class="Special"&gt;::&lt;/span&gt;Long &lt;span class="Statement"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="Number"&gt;10.0&lt;/span&gt;
&lt;span id="L20" class="LineNr"&gt;20 &lt;/span&gt;        }
&lt;span id="L21" class="LineNr"&gt;21 &lt;/span&gt;    }
&lt;span id="L22" class="LineNr"&gt;22 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

Here you can see me using pattern matching, another Rust feature. It's similar 
in usage to a switch statement in C but semantically very different. Cases in 
switch blocks are just gotos; pattern matching has required coverage 
completeness. You have to cover every case for it to compile. Plus you can 
match on ranges and other constructs that makes it a lot more flexible.

So, now that we've implemented this trait for these two types, we can have a 
generic function[^4].

&lt;html&gt;
&lt;div class=code&gt;
&lt;pre id='vimCodeElement' style="overflow-x: scroll; width: 100%; white-space: pre;"&gt;
&lt;span id="L1" class="LineNr"&gt;1 &lt;/span&gt;&lt;span class="Keyword"&gt;fn&lt;/span&gt; &lt;span class="Function"&gt;pet&lt;/span&gt;&lt;span class="Statement"&gt;&amp;lt;&lt;/span&gt;T: Rateable&lt;span class="Statement"&gt;&amp;gt;&lt;/span&gt;(boi: T) &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Type"&gt;&amp;amp;&lt;/span&gt;&lt;span class="Type"&gt;str&lt;/span&gt; {
&lt;span id="L2" class="LineNr"&gt;2 &lt;/span&gt;    &lt;span class="Statement"&gt;match&lt;/span&gt; boi.&lt;span class="Function"&gt;fluff_rating&lt;/span&gt;() {
&lt;span id="L3" class="LineNr"&gt;3 &lt;/span&gt;        &lt;span class="Number"&gt;0.0&lt;/span&gt;...&lt;span class="Number"&gt;3.5&lt;/span&gt; &lt;span class="Statement"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;naked alien boi...but precious nonetheless&amp;quot;&lt;/span&gt;,
&lt;span id="L4" class="LineNr"&gt;4 &lt;/span&gt;        &lt;span class="Number"&gt;3.5&lt;/span&gt;...&lt;span class="Number"&gt;6.5&lt;/span&gt; &lt;span class="Statement"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;increased floof...increased joy&amp;quot;&lt;/span&gt;,
&lt;span id="L5" class="LineNr"&gt;5 &lt;/span&gt;        &lt;span class="Number"&gt;6.5&lt;/span&gt;...&lt;span class="Number"&gt;8.5&lt;/span&gt; &lt;span class="Statement"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;approaching maximum fluff&amp;quot;&lt;/span&gt;,
&lt;span id="L6" class="LineNr"&gt;6 &lt;/span&gt;        _ &lt;span class="Statement"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;sublime. the softest boi!&amp;quot;&lt;/span&gt;
&lt;span id="L7" class="LineNr"&gt;7 &lt;/span&gt;}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/html&gt;

Like in C++, the stuff inside the angle brackets is our type arguments. But 
unlike C++ templates, we are able to parametrise the function. We're able to 
say "this function is only for types that are Rateable". That's not something 
you can do in C++![^5] This has consequences beyond readability. Trait bounds 
on type arguments means the Rust compiler can type check the function once, 
rather than having to check each concrete instantiation separately. This means 
faster compilation and clearer compiler error messages.

You can also use traits dynamically, which isn't preferred as it has a runtime
penalty, but is sometimes necessary. I decided it was best not to cover that in 
this post.

One other big part of traits is the interoperability that comes from standard
traits, like `Add` and `Display`. Implementing add means you can add a type
together with the + operator, implementing Display means you can print it.

# Rust tools
C and C++ don't have a standard way to manage dependencies. There's a few 
different tools for doing this, I haven't heard great things about any of them. 
Using plain Makefiles for your build system is very flexible, but can be 
rubbish to maintain. CMake reduces the maintenance burden but is less flexible 
which can be frustrating.

Rust really shines in this respect. Cargo is the one and only tool used in the 
Rust community for dependency management, packaging and for building and 
running your code. It's similar in many ways to Pipenv and Poetry in Python. 
There's an official package repository to go along with it. I don't have a lot 
more to say about this! It's really nice to use and it makes me sad that C and 
C++ don't have the same thing.

![cargo](/images/rust-talk/cargo.png "cargo usage screenshot")

# Should we all use Rust?
There's no universal answer for this. It depends on your application, as with 
any programming language. Rust is already being used very successfully in many 
different places. Microsoft use it for Azure IoT stuff, Mozilla sponsor Rust 
and use it for parts of the Firefox web browser, and many smaller companies are 
using it too.

So depending on your application, it's very much production ready.

&lt;html&gt;
&lt;div class=info_box&gt;
Rust is already being used in production successfully
&lt;br&gt;&lt;br&gt;
But for some applications you might find support immature or lacking.
&lt;/div&gt;
&lt;/html&gt;

### Embedded
In the embedded world, how ready Rust is depends on what you are doing. There 
are mature resources for Cortex-M that are used in production, and there's a 
developing but not yet mature RISC-V toolchain.

For x86 and arm8 bare metal the story is also good, like for Raspberry Pis.
For more vintage architectures like PIC and AVR there isn't great support but I 
don't think for most new projects that should be a big issue.

Cross compilation support is good for all LLVM targets because the Rust 
compiler uses LLVM as its backend.

One thing where embedded Rust is lacking is there are no production grade
RTOSs, and HALs
are less developed. This isn't an insurmountable issue for many projects, but 
it would certainly hamper many too. I expect this to continue growing in the 
next couple years.

### Async
One thing that definitely isn't ready is language async support which is still 
in development. They're still deciding what the async/await syntax should look 
like.

### Interoperability
As for interoperability with other languages, there's a good C FFI in Rust, but 
you have to go through that if you want to call Rust from C++ or vice versa. 
That's very common in many languages, I don't expect it to change. I
mention it because it would make it a bit of a pain to incorporate Rust into an 
existing C++ project: you'd need a C layer between the Rust and C++ and that 
would potentially be adding a lot of complexity.

### Final thoughts
Were I starting from scratch on a new project at work I would definitely vouch 
for Rust. I'm really hopeful that it
represents a better future for software &amp;ndash; one that's more reliable, more
secure and more enjoyable to write.

[^1]: from Ian Barland's ["Why C and C++ are Awful Programming 
Languages"](http://www.radford.edu/ibarland/Manifestoes/whyC++isBad.shtml)

[^2]: The value categories used to just be lvalues (which has an identifiable 
place in memory) and rvalues (which do no not, like literals). It is now [much 
more complicated](https://en.cppreference.com/w/cpp/language/value_category).

[^3]: Yes...I should have had a test already. But for various unjustified 
reasons I didn't write a test that covered this particular code until later.

[^4]: Note: cheekily, I included this code that would not actually compile. 
You’d need the return type to be `&amp;’static str`. This is “lifetime annotation” 
and was outside the scope of my talk, and this blog post. Read about it 
[here](https://doc.rust-lang.org/1.9.0/book/lifetimes.html).

[^5]: I hear a lot of people say that Concepts in C++20 are analogous to 
traits, but this isn't true. I explain why 
[here](https://mcla.ug/blog/cpp20-concepts-are-not-like-rust-traits.html)</content><category term="misc"/></entry></feed>