<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Owen Gallagher</title>
    <description>The latest articles on DEV Community by Owen Gallagher (@owengall).</description>
    <link>https://dev.to/owengall</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F602646%2Ff54c6d21-bf3d-41ed-9fb2-6035746986ea.png</url>
      <title>DEV Community: Owen Gallagher</title>
      <link>https://dev.to/owengall</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/owengall"/>
    <language>en</language>
    <item>
      <title>JavaScript type detection</title>
      <dc:creator>Owen Gallagher</dc:creator>
      <pubDate>Fri, 21 Jan 2022 02:44:13 +0000</pubDate>
      <link>https://dev.to/owengall/javascript-type-detection-13h3</link>
      <guid>https://dev.to/owengall/javascript-type-detection-13h3</guid>
      <description>&lt;p&gt;This is one of those annoying things I have to relearn every time I come back to writing something in JS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;
&lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;wow&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;course&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That, and &lt;a href="https://dev.to/search?q=javascript%20this"&gt;&lt;code&gt;this&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>javascript</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Multilingual wordsearch generator</title>
      <dc:creator>Owen Gallagher</dc:creator>
      <pubDate>Mon, 29 Nov 2021 05:14:22 +0000</pubDate>
      <link>https://dev.to/owengall/multilingual-wordsearch-generator-489g</link>
      <guid>https://dev.to/owengall/multilingual-wordsearch-generator-489g</guid>
      <description>&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;As a language1 learner most recently interested in Korean/한국어, I've been practicing a lot of new vocabulary. Practicing vocabulary can become tedious if I just follow the same kinds exercises (ex. Duolingo, Memrise, physical flashcards) over and over again.&lt;/p&gt;

&lt;p&gt;One twist on the flashcards strategy for vocabulary would be a puzzle like a crossword or a wordsearch. Between the two, a crossword is much harder to improvise, as it requires words to share certain letters/characters so they can be organized with crosses. &lt;/p&gt;

&lt;p&gt;So, given that they'd be a bit easier to create quickly, I chose to try using custom wordsearches. The plan was to pick a handful of words, maybe by topic, or by difficulty, or randomly, and put them in a wordsearch puzzle together.&lt;/p&gt;

&lt;p&gt;... But I couldn't find a good wordsearch generator. There were a bunch I found, but none of them supported different character sets (as far as I cared to figure out).&lt;/p&gt;

&lt;p&gt;That's how I decided to make my own.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;At the core of being able to support different languages in my wordsearch generator is the &lt;code&gt;alphabets.json&lt;/code&gt; file, which currently looks like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;alphabets.json&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;   
    &lt;/span&gt;&lt;span class="nl"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ranges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"upper_ranges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"es"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ranges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;122&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;225&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;233&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;237&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;243&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="nl"&gt;"upper_ranges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;193&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;205&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;211&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;218&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;220&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ko"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ranges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;44032&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;55203&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="nl"&gt;"upper_ranges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;44032&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;55203&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Valid characters from which to pick random ones when initially randomizing the wordsearch cells are defined by &lt;em&gt;"ranges"&lt;/em&gt;, though they're more like sets. If I list two values, that means &lt;strong&gt;all unicode points between &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;&lt;/strong&gt;. Any other number of values means &lt;strong&gt;all these unicode points &lt;code&gt;a&lt;/code&gt;,&lt;code&gt;b&lt;/code&gt;,...,&lt;code&gt;z&lt;/code&gt;&lt;/strong&gt;. Being able to list noncontiguous points makes it easy to include sparse characters like accented vowels used in Spanish (see &lt;code&gt;es&lt;/code&gt;).2&lt;/p&gt;

&lt;p&gt;Once the language alphabet can be defined with this system, the generator is able to fill cells with random characters and later populate some of them with hidden words that the user provides.&lt;/p&gt;

&lt;p&gt;My placement algorithm for the hidden words is essentially brute-force. I pick a direction and then try random spots until I find available space, with a maximum number of attempts, beyond which the word is skipped.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;The current best-supported method of providing configuration/description/input for generating a wordsearch is via a &lt;code&gt;json&lt;/code&gt; file, like so:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;example_en.json&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"words"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"apple:a fruit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"skull:head bone"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"scissors:cuts paper"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"boat:floats on water"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"bird:feathers and beaks"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Generating a puzzle like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvf2gxq26d7fhm4nscf3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvf2gxq26d7fhm4nscf3v.png" alt="example English puzzle" width="736" height="759"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Extension
&lt;/h2&gt;

&lt;p&gt;Note that, hopefully, this implementation is extensible enough to easily support other languages (add entries in &lt;code&gt;alphabets.json&lt;/code&gt;), including arbitrary character sets.&lt;/p&gt;

&lt;p&gt;I'm also considering making a printer-friendly output option in the webpage example so that the generated wordsearch is easy to make into a physical worksheet.&lt;/p&gt;
&lt;h2&gt;
  
  
  Source code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ogallagher" rel="noopener noreferrer"&gt;
        ogallagher
      &lt;/a&gt; / &lt;a href="https://github.com/ogallagher/wordsearch_generator" rel="noopener noreferrer"&gt;
        wordsearch_generator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Multilingual wordsearch (word search) generator
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Footnotes
&lt;/h2&gt;

&lt;p id="foot-one"&gt;
&lt;b&gt;Language&lt;/b&gt; here refers to, at least, programming languages and human/natural languages.
&lt;/p&gt;

&lt;p id="foot-two"&gt;
In order to also support cases (upper, lower) for alphabets like that of English, I added the &lt;code&gt;"upper_ranges"&lt;/code&gt; attribute.
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>gamedev</category>
      <category>node</category>
    </item>
    <item>
      <title>Tetracoords theory - triangular 2D scalar arithmetic</title>
      <dc:creator>Owen Gallagher</dc:creator>
      <pubDate>Sun, 08 Aug 2021 20:24:25 +0000</pubDate>
      <link>https://dev.to/owengall/tetracoords-theory-triangular-2d-scalar-arithmetic-36m4</link>
      <guid>https://dev.to/owengall/tetracoords-theory-triangular-2d-scalar-arithmetic-36m4</guid>
      <description>&lt;h2&gt;
  
  
  Justification and inspiration
&lt;/h2&gt;

&lt;p&gt;I was originally inspired by the &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Geohash" rel="noopener noreferrer"&gt;geohash&lt;/a&gt;&lt;/strong&gt; coordinate system, proposed as an alternative to latitude-longitude coordinates for mapping the Earth’s surface, and by later proposals like &lt;strong&gt;&lt;a href="https://github.com/google/open-location-code/blob/main/docs/specification.md" rel="noopener noreferrer"&gt;plus codes&lt;/a&gt;&lt;/strong&gt;. Tetracoordinates are not meant to compete with either of those proposals for use as geographical coordinates, and I hope that plus code or a derivative continues to improve and be more widely adopted for addressing and navigation.&lt;/p&gt;

&lt;p&gt;The tetracoords system rather tries to address specific issues with the geohash approach while keeping many of the same advantages, focusing especially on use in software (as opposed to being human-readable).&lt;/p&gt;

&lt;p&gt;For example, imagine you’re creating a 2D multiplayer game, where all objects and avatars need to have assigned positions. Using traditional 2D vectors, you then need to determine a scale and precision for that game space. If you use integers, then nothing can be at position &lt;strong&gt;0.5,-0.5&lt;/strong&gt; because an integer doesn’t allow for precision at place value 10^-1. If you use floats, then the further something is from the origin &lt;strong&gt;0,0&lt;/strong&gt;, the less digits its position can allocate for determining precision, and vice versa. These limitations usually mean that the dimensions (and max zoom level) of the game space cannot grow over time.&lt;/p&gt;

&lt;p&gt;Using a tetracoord-based datatype, however, you don’t need to specify scale or precision beforehand, and different tetracoords with different numbers of significant digits (of different sizes in memory) can be used for different contexts as needed (a fast airplane has high scale, but a slow ant has high precision).&lt;/p&gt;

&lt;p&gt;Below are some key advantageous characteristics of tetracoordinates:&lt;/p&gt;

&lt;h3&gt;
  
  
  Centered
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyavjo8v5lrobs9yboaou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyavjo8v5lrobs9yboaou.png" alt="tetracoord_origin" width="130" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The origin, marked as cell zero above, is centered. This is crucial for later being able to increase scale (outward) and precision (inward), because the current outermost cell is the center/origin of the next level.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzz397b1c149j0osbqb0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzz397b1c149j0osbqb0.png" alt="tetracoords_nested_origin" width="242" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just as in cartesian coordinates with base-10 numbers, where the more significant (leading) and less significant (trailing) digits can be implied zeros (15 = 015 = 0015 = 15.0 = 15.00), tetracoords can behave the same way.&lt;/p&gt;

&lt;p&gt;In a system like geohash, however, since there is an even number of cells in a square grid, then the cell designated as zero, the origin, is &lt;strong&gt;not&lt;/strong&gt; centered, but rather at a corner. If you try to scale outward, then that cell will need to be in the same corner of a larger square, thus only allowing scaling in only two directions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsf0yvgkiji222vopk0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsf0yvgkiji222vopk0f.png" alt="geohash_scaling" width="291" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note geohash doesn’t typically use only 4 cells per level, but I’ve modified slightly for comparison.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Recursive
&lt;/h3&gt;

&lt;p&gt;In order to scale inward and outward uniformly, the layout of the cells is recursive, as in geohash.&lt;/p&gt;

&lt;h3&gt;
  
  
  Base-2/binary compatible
&lt;/h3&gt;

&lt;p&gt;Using four (a power of 2) cells per level makes a tetracoord binary-compatible for efficient storage as a datatype in software.&lt;/p&gt;

&lt;p&gt;For example, the base-4 tetracoord &lt;strong&gt;0.1.3&lt;/strong&gt; is equal to the binary tetracoord &lt;strong&gt;00.01.11&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Determinate
&lt;/h3&gt;

&lt;p&gt;Just as in geohash, tetracoord cells never overlap, so there is only one coordinate mapping for any cell. However, any theoretical point exactly on the border or vertex between cells is irrational and indeterminate, much in the same way that &lt;strong&gt;3/3&lt;/strong&gt; equals &lt;strong&gt;0.9999...&lt;/strong&gt; equals &lt;strong&gt;1.0&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mathematical nonnegative scalars
&lt;/h3&gt;

&lt;p&gt;Tetracoord values, though they represent locations in 2-dimensional space, are nonnegative scalar values. This means they don’t need to be represented with multiple components as do cartesian coordinate vectors.&lt;/p&gt;

&lt;p&gt;Additionally, and more importantly, tetracoords can still support arithmetic operations (addition, subtraction, multiplication, division, etc), though these operations behave according to laws wholly different from both scalar and vector arithmetic in the number systems we normally use. &lt;/p&gt;

&lt;p&gt;However, if the algebraic laws and arithmetic patterns for tetracoords are properly defined, then methods can be written to perform tetracoord arithmetic without the need to convert to a different number space (like cartesian space).&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition
&lt;/h2&gt;

&lt;p&gt;Consider a 2-dimensional space, organized into nested equilateral triangles, like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9s97aksigzmhv9rsc78v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9s97aksigzmhv9rsc78v.png" alt="fractal_levels" width="640" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj94lgkgc6s9wfc8ao7kd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj94lgkgc6s9wfc8ao7kd.PNG" alt="sierpinski_triangle_wikimedia" width="709" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the famous Sierpinski Triangle fractal, which ideally would be infinitely large, with an infinite number of subdivisions. In other words, each triangular cell in this infinitely large space is also infinitely small. In practice, however, the implementation of tetracoordinates in a 2D space would always be truncating scale and precision depending on what’s needed.&lt;/p&gt;

&lt;p&gt;Now, for creating a tetracoord space, don’t leave the central cells empty, creating a denser (and more boring) version of the fractal. The coordinate value of each cell at each level uses the center cell as 0, and the rest in counterclockwise order, starting with the vertically offset cell, as 1, 2, and 3:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj17cxwfwy92b8vt9pgfj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj17cxwfwy92b8vt9pgfj.png" alt="tetracoords_values" width="407" height="360"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Some cells are left intentionally blank to save myself the effort.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Syntax
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Binary and quaternary bases
&lt;/h3&gt;

&lt;p&gt;In this article I switch between base-4 and base-2 representations, which are effectively equivalent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;base-4 (quaternary)&lt;/strong&gt;: &lt;code&gt;1.3.2.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;base-2 (binary)&lt;/strong&gt;: &lt;code&gt;01.11.10.00&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Of course, other bases could be used for compression or legibility, removing the dot delimiters between levels:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;base-4 (quaternary)&lt;/strong&gt;: &lt;code&gt;1320&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;base-8 (octal)&lt;/strong&gt;: &lt;code&gt;170&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;base-16 (hexadecimal)&lt;/strong&gt;: &lt;code&gt;78&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Delimiters
&lt;/h4&gt;

&lt;p&gt;I use the dot as a place value separator (like ip address byte delimiters), and a double dot after the origin place value (analagous to the point in real decimal numbers).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;01.00.10&lt;/strong&gt; = &lt;strong&gt;01.00.10..&lt;/strong&gt; = &lt;strong&gt;01.00.10..00&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;..11&lt;/strong&gt; = &lt;strong&gt;00..11&lt;/strong&gt; = &lt;strong&gt;0..3&lt;/strong&gt; (quaternary)&lt;/p&gt;

&lt;p&gt;Note that the dot and double dot notation isn’t really necessary when writing tetracoords in base-4, but I’ll use them for consistency.&lt;/p&gt;

&lt;h4&gt;
  
  
  Algebra
&lt;/h4&gt;

&lt;p&gt;I use a specific notation for algebra, given that at each level there are only four possible values: 00, 01, 10, 11. I use the following variables:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;x, y, z, 0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;not as placeholders for full tetracoord values, but instead as placeholders for levels within a value. &lt;strong&gt;0&lt;/strong&gt; is always &lt;strong&gt;00&lt;/strong&gt;, but &lt;strong&gt;x&lt;/strong&gt;, &lt;strong&gt;y&lt;/strong&gt;, and &lt;strong&gt;z&lt;/strong&gt; refer to any value other than zero: &lt;strong&gt;01&lt;/strong&gt;, &lt;strong&gt;10&lt;/strong&gt;, or &lt;strong&gt;11&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Irrationals
&lt;/h4&gt;

&lt;p&gt;Any point (aka. a cell of infinite precision) on an edge between cells or on a vertex (where edges meet) is an irrational tetracoordinate.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note that a point along an edge will also be a vertex at a higher specificity.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To denote an irrational number with infinitely repeating digits at each level, I use bar notation, as in:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;x̄&lt;/strong&gt; &lt;strong&gt;ȳ&lt;/strong&gt; &lt;strong&gt;z̄&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;x.y..y.y.y...&lt;/strong&gt; = &lt;strong&gt;x.y..ȳ&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Arithmetic
&lt;/h2&gt;

&lt;p&gt;Tetracoords arithmetic is &lt;strong&gt;not&lt;/strong&gt; intuitive compared to traditional, &lt;em&gt;normal&lt;/em&gt;, real numbers, and the rules defined below are derived geometrically, given some basic properties of an equilateral triangle:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpfcgqqxht8q9tok2zha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpfcgqqxht8q9tok2zha.png" alt="tetracoords_equilateral_geometry" width="783" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Please correct me if I’m wrong in the generalizations below!&lt;/strong&gt; These are key foundational laws for being able to perform tetracoord arithmetic and later use a tetracoord datatype implementation in programs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Algebraic laws (so far)
&lt;/h3&gt;

&lt;p&gt;These laws are a work in progress and so far only touch on the most basic arithmetic operations.&lt;/p&gt;

&lt;p&gt;0 + 0 = 0&lt;/p&gt;

&lt;p&gt;0 + x = x&lt;/p&gt;

&lt;p&gt;0 - x = 0..x̄&lt;/p&gt;

&lt;p&gt;(note that negatives do, in fact, exist,&lt;br&gt;
in order to allow subtraction, but have&lt;br&gt;
equivalent positive values)&lt;/p&gt;

&lt;p&gt;-z = 0..z̄&lt;br&gt;
   = x..ȳ&lt;br&gt;
   = y..x̄&lt;br&gt;
   = z.x..ȳ&lt;br&gt;
   = z.y..x̄&lt;br&gt;
   = z.0..z̄&lt;/p&gt;

&lt;p&gt;x + x = x..x̄&lt;br&gt;
      = 2x&lt;br&gt;
      = y.z..z̄&lt;br&gt;
      = z.y..ȳ&lt;br&gt;
      = x.0.x..x̄&lt;br&gt;
      = x.y.z..z̄&lt;br&gt;
      = x.z.y..ȳ&lt;/p&gt;

&lt;p&gt;x.y = x.0 - y&lt;/p&gt;

&lt;p&gt;x + y + z = 0&lt;br&gt;
x + y = -z&lt;/p&gt;

&lt;p&gt;x - y = y.z&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiples formula
&lt;/h3&gt;

&lt;p&gt;Just as when performing real arithmetic, there are shortcuts that mathematicians have discovered by studying patterns. For example, to compute &lt;code&gt;5 * 30&lt;/code&gt; you don’t need to compute &lt;code&gt;5 + 5 + 5 + ... + 5&lt;/code&gt;, but can rather do something like &lt;code&gt;(5 * 3) * 10&lt;/code&gt;. Along these lines I’ve determined the following formulas to calculate any positive multiple of &lt;strong&gt;x&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;k&lt;/code&gt; is a real number constant.&lt;br&gt;
&lt;code&gt;x&lt;/code&gt; and &lt;code&gt;t&lt;/code&gt; are tetracoord values, where a subscript &lt;code&gt;n&lt;/code&gt; refers to a digit within the tetracoord.&lt;br&gt;
&lt;code&gt;po(n)&lt;/code&gt; means pattern offset formula.&lt;br&gt;
&lt;code&gt;pl(n)&lt;/code&gt; means pattern length formula.&lt;/p&gt;

&lt;p&gt;Shout out to the &lt;a href="https://math.stackexchange.com/q/4201199/950981" rel="noopener noreferrer"&gt;math.stackexchange.com community for assisting&lt;/a&gt; in the definition of these formulas!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zxqaqa6n6nv7wt0eohx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zxqaqa6n6nv7wt0eohx.png" alt="tetracoords_mult_pattern" width="284" height="363"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;See brainstorming for some messy notes on the derivation.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Below are the results (hopefully) each multiple &lt;code&gt;k*x&lt;/code&gt; in set of &lt;code&gt;k = 0, 1, ..., 11&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;k&lt;/th&gt;
&lt;th&gt;t&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0.0.0.0.0..0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.0.0.0.x..0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.0.0.0.x..x̄&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0.0.x.0.x..0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0.0.x.0.0..0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;0.0.x.0.0..x̄&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;0.0.x.x.0..0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;0.0.x.x.x..0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0.0.x.x.x..x̄&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;x.0.x.x.x..0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;x.0.x.x.0..0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;x.0.x.x.0..x̄&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqdvp9tudpp3glyr2gg7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqdvp9tudpp3glyr2gg7.png" alt="tetracoords_mult_trail" width="800" height="685"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Future research
&lt;/h2&gt;

&lt;p&gt;Explore more advanced tetracoord algebra (multiplication and division, exponents and roots, rules for decomposition and composition at different levels, etc).&lt;/p&gt;

&lt;p&gt;Implement a functioning tetracoord datatype in any programming language that leverages its advantages (variable scale and precision, native tetracoord arithmetic, conversion to and from cartesian vector coords).&lt;/p&gt;

&lt;p&gt;Create a GUI 2D map navigator that shows tetracoord cells at different specificities and scales and shows equivalent cartesian and tetra coordinates.&lt;/p&gt;

&lt;p&gt;Extend a similar system to 3D and possibly further dimensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Brainstorming
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multiples pattern search
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62le9c6pkz5737rt0585.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62le9c6pkz5737rt0585.jpg" alt="mult_formula_derive_1" width="637" height="942"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fey9g08onmo5mpkh8xl05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fey9g08onmo5mpkh8xl05.png" alt="mult_formula_derive_2" width="640" height="1136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiples pattern length and offset formulas
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmvp5fiofqp6e0scql5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmvp5fiofqp6e0scql5j.png" alt="mult_formula_recurse_1" width="640" height="1136"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugl5ajwu8ek7pohscgxj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugl5ajwu8ek7pohscgxj.png" alt="mult_formula_recurse_2" width="640" height="1136"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>geometry</category>
      <category>recursion</category>
      <category>coordinates</category>
      <category>math</category>
    </item>
    <item>
      <title>Google Drive anonymous animals – Collect them all!</title>
      <dc:creator>Owen Gallagher</dc:creator>
      <pubDate>Sat, 12 Jun 2021 03:18:18 +0000</pubDate>
      <link>https://dev.to/owengall/google-drive-anonymous-animals-collect-them-all-32e4</link>
      <guid>https://dev.to/owengall/google-drive-anonymous-animals-collect-them-all-32e4</guid>
      <description>&lt;h2&gt;
  
  
  Questions
&lt;/h2&gt;

&lt;p&gt;I’ve always been interested in the animal icons that users are assigned when accessing a Google document anonymously, but only recently did I seriously start wondering:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many are there?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are they available via some sort of API or image server?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Searching
&lt;/h2&gt;

&lt;p&gt;So, I began searching the internet. See the end for some related pages I found and stuff I used for reference.&lt;/p&gt;

&lt;p&gt;I figured since these animals have been around for years and since Google is one of the biggest names on the internet, that it should be pretty easy to answer these questions... &lt;/p&gt;

&lt;h2&gt;
  
  
  The image source
&lt;/h2&gt;

&lt;p&gt;But no! Nobody seems to know for sure how many there are. There are many lists of varying lengths out there, and it’s difficult to create a definitive one, as it seems animals have been both deleted and created since their introduction.&lt;/p&gt;

&lt;p&gt;After many hours of searching, I still not found anything published by Google itself that lists the anonymous animals, though admittedly I haven’t asked anyone that works there directly.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;However&lt;/em&gt;, I did look into the source for the anonymous icon image that appears in a doc webpage, and found this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://ssl.gstatic.com/docs/common/profile/&amp;lt;animal-name&amp;gt;_lg.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;lg&lt;/code&gt; (large) is the size of the image, though I’ve not checked whether other image sizes are available. So, all possible anonymous animal images are supposedly located at &lt;code&gt;ssl.gstatic.com/docs/common/profile/&lt;/code&gt;, though I don’t know of an easy way to list all valid image files under that path.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Well&lt;/em&gt; – I thought – &lt;em&gt;maybe I could just guess and check?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My own list
&lt;/h2&gt;

&lt;p&gt;So, I compiled as complete a list of animal names as I could find and attempted to check if each existed, with code like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;check_animal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://ssl.gstatic.com/docs/common/profile/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_lg.png`&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// anonymous animal found!&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// anonymous animal not found&lt;/span&gt;
      &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The results were promising, but comparing with other lists on the internet I saw that there were some I was missing, because some anonymous animals are actually fictional creatures (ex. unicorn, dragon, nyan cat, jackalope), have special names (ex. dumbo octopus, slow loris), or animals at all (ex. pumpkin)! In these cases, I just grabbed names that other people had shared previously and added them to my list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Showcase
&lt;/h2&gt;

&lt;p&gt;Now, if you’d like to see what may be the most complete list of Google Anonymous Animals on the internet, check mine out at &lt;strong&gt;&lt;a href="https://o.dreamhosters.com/anonymousanimals" rel="noopener noreferrer"&gt;o.dreamhosters.com/anonymousanimals&lt;/a&gt;&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7mohjwoyrajkznpid0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7mohjwoyrajkznpid0g.png" alt="anonymous_animals_preview_col" width="458" height="788"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;So far, any time an animal has a space in its name (ex. nyan cat, slow loris), the corresponding filename has no space (ex. &lt;code&gt;nyancat_lg.png&lt;/code&gt;, &lt;code&gt;slowloris_lg.png&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://o.dreamhosters.com/anonymousanimals/zoo.json" rel="noopener noreferrer"&gt;zoo.json&lt;/a&gt; for my list of animal name candidates that are used to discover anonymous animal images on Google’s server.&lt;/p&gt;

&lt;p&gt;Source code for my anonymous animals page is available at &lt;a href="https://github.com/ogallagher/google_drive_anonymous_animals" rel="noopener noreferrer"&gt;github.com/ogallagher/google_drive_anonymous_animals&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://gist.github.com/rockwotj/6a356a95732985b09e2b%E2%80%9D&amp;gt;%0Agithub.com/rockwotj/download_anonymous_icons_from_drive.rb%0A&amp;lt;/a&amp;gt;%20%E2%80%93%20Ruby%20script%20written%20to%20download%20anonymous%20animal%20images%20given%20a%20defined%20list.%0A&amp;lt;/li&amp;gt;%0A&amp;lt;li&amp;gt;%0A&amp;lt;a%20href=" rel="noopener noreferrer"&gt;                            wayou.github.io/anonymous-animals
&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://a-z-animals.com/animals/" rel="noopener noreferrer"&gt;
a-z-animals.com/animals
&lt;/a&gt; – I just scraped an animal list from this site for my initial attempt at animal discovery.
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jeffersoncheng.com/Anonymous-Animals" rel="noopener noreferrer"&gt;
jeffersoncheng.com/anonymous-animals
&lt;/a&gt; - This designer was contracted to design many of the anonymous animals.
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.musesrealm.net/deities/creatures.html" rel="noopener noreferrer"&gt;
musesrealm.net/deities/creatures
&lt;/a&gt; – I scraped an initial fictional animals list from this site.
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@roeder/these-are-all-of-the-anonymous-google-docs-animals-i-have-seen-so-far-8e33e0405993" rel="noopener noreferrer"&gt;
medium.com/@roeder
&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://evert.meulie.net/faqwd/complete-list-anonymous-animals-on-google-drive-docs-sheets-slides/%E2%80%9C&amp;gt;%0Aevert.meulie.net/faqwd%0A&amp;lt;/a&amp;gt;%0A&amp;lt;/li&amp;gt;%0A&amp;lt;li&amp;gt;%0A&amp;lt;a%20href=" rel="noopener noreferrer"&gt;
mentalfloss.com, by Claire Shefchik
&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Collect them all!
&lt;/h2&gt;

&lt;p&gt;If you are aware of other anonymous animals that don’t appear in my list, let me know and I’ll add them!&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>png</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Define sinstructor</title>
      <dc:creator>Owen Gallagher</dc:creator>
      <pubDate>Fri, 30 Apr 2021 02:49:28 +0000</pubDate>
      <link>https://dev.to/owengall/define-sinstructor-306</link>
      <guid>https://dev.to/owengall/define-sinstructor-306</guid>
      <description>&lt;h2&gt;
  
  
  sinstructor (n)
&lt;/h2&gt;

&lt;p&gt;Computer code in any object-oriented program that defines new members of an object instance outside of its constructor, resulting in unnecessary confusion and forgotten variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# a happy constructor
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wheel_count&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wheel_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wheel_count&lt;/span&gt;
    &lt;span class="c1"&gt;# end __init__
# end Vehicle
&lt;/span&gt;
&lt;span class="n"&gt;motorbike&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wheel_count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# CAUTION: SINSTRUCTOR AHEAD
&lt;/span&gt;&lt;span class="n"&gt;motorbike&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#ff0000&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// a happy constructor (sort of)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Vehicle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wheel_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wheel_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wheel_count&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;motorbike&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// CAUTION: SINSTRUCTOR AHEAD&lt;/span&gt;
&lt;span class="nx"&gt;motorbike&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ff0000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is this a new term? I derived it by taking &lt;strong&gt;con&lt;/strong&gt;structor (with) and switching it to &lt;strong&gt;sin&lt;/strong&gt;structor (without).&lt;/p&gt;

</description>
      <category>oop</category>
      <category>vocabulary</category>
      <category>watercooler</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Relational tags</title>
      <dc:creator>Owen Gallagher</dc:creator>
      <pubDate>Wed, 24 Mar 2021 04:40:23 +0000</pubDate>
      <link>https://dev.to/owengall/relational-tags-29n9</link>
      <guid>https://dev.to/owengall/relational-tags-29n9</guid>
      <description>&lt;h1&gt;
  
  
  Why not?
&lt;/h1&gt;

&lt;p&gt;Let's combine the best of two disparate organizational systems: tree hierarchy, and tags.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5tmd6zkesbzd0xrennt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5tmd6zkesbzd0xrennt.png" alt="tree hierarchy graph" width="800" height="773"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;tree&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Very intuitive for grouping, and maintaining a spatial metaphor (ex. file system with folders, geolocation with quadrants).&lt;/li&gt;
&lt;li&gt;Memorable relationships between entities, permitting easy search by incrementing specificity (&lt;code&gt;users &amp;gt; myself &amp;gt; images &amp;gt; cats &amp;gt; fat_cat.png&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;tags&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;More improvised/ad hoc approach, where organization evolves organically without knowing what is more or less specific.&lt;/li&gt;
&lt;li&gt;Less rigid classification than the hierarchy tree, with loose relationships.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Relational tags would have the flexibility of tags, with an additional layer of association by defining relationships between tags. I wonder if something like this concept is used in applications like knowledge graphs and mapping natural languages.&lt;/p&gt;

&lt;p&gt;For example, I’ll organize the following entities according to the three systems. Note there are certainly many ways to do so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apple, banana, cat, dandelion, grass, 
mouse, school bus, strawberry, Rudolph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Tree example
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- alive
    - plant
        - yellow
            - banana
            - dandelion
        - red
            - apple
            - strawberry
        - green
            - grass
    - animal
        - cat
        - mouse
        - Rudolph
- inanimate
    - school bus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note, for example, that I didn’t put &lt;code&gt;school bus&lt;/code&gt; in &lt;code&gt;yellow&lt;/code&gt; because it’s only allowed to have one parent node. A filesystem typically gets around this with aliases/symbolic links/shortcuts/etc.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tags example
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- apple - fruit, plant, alive, red, sweet
- banana - fruit, plant, alive, yellow, sweet
- cat - animal, alive, mammal, carnivore
- dandelion - plant, alive, yellow, flower, bitter
- grass - plant, alive, green, bitter
- mouse - animal, alive, mammal, herbivore
- school bus - inanimate, yellow
- strawberry - red, plant, red, sweet, alive
- Rudolph - alive, animal, red, fiction, herbivore, mammal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note here that adding new entities to this system becomes tedious, and entity-tag assignments are easily forgotten.&lt;/p&gt;

&lt;h1&gt;
  
  
  Relational tags example
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Tag relationships&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These could be directed or not; I’m not sure which is more useful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alive --&amp;gt; animal, plant, animate
inanimate
color --&amp;gt; red, yellow, green
animal --&amp;gt; mammal, carnivore, herbivore
plant --&amp;gt; fruit, vegetable, flower
fruit --&amp;gt; sweet
flavor --&amp;gt; sweet, bitter
existence --&amp;gt; reality, fiction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Entity-tag assignments&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Apple - plant, fruit, red
Banana - fruit, yellow
Cat - mammal, carnivore
Dandelion - flower
Grass - plant
Mouse - mammal
School bus - yellow, inanimate
Strawberry - fruit, red
Rudolph - animal, fictional
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hooray! Now, an entity can belong to any number of tags, &lt;strong&gt;and&lt;/strong&gt; tags have relationships with each other, so I don’t need to remember to add &lt;code&gt;alive&lt;/code&gt; and &lt;code&gt;plant&lt;/code&gt; to all of my &lt;code&gt;fruit&lt;/code&gt; entities.&lt;/p&gt;

&lt;p&gt;If I change my mind about the tag relationships, I can easily redefine them.&lt;/p&gt;

&lt;p&gt;If I want to search for entities, I can search by tags and the tag relationships will pull in entities assigned to related tags as well.&lt;/p&gt;

&lt;h1&gt;
  
  
  P.S.
&lt;/h1&gt;

&lt;p&gt;This is more a discussion/opinion thread than anything else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is this a new concept, or a new application for an existing concept, or neither?&lt;/strong&gt; The most immediate application I can think of from a user perspective is a computer’s file system, where the strict tree structure can become cumbersome.&lt;/p&gt;

&lt;p&gt;If you’ve seen this implemented in an existing operating system or software framework I’d much like to know about it.&lt;/p&gt;

</description>
      <category>relational</category>
      <category>organization</category>
      <category>graph</category>
      <category>trees</category>
    </item>
  </channel>
</rss>
