<?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: torrua</title>
    <description>The latest articles on DEV Community by torrua (@torrua).</description>
    <link>https://dev.to/torrua</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F727131%2Fd30873f8-1649-4337-ba94-542f48d3f4c4.jpeg</url>
      <title>DEV Community: torrua</title>
      <link>https://dev.to/torrua</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/torrua"/>
    <language>en</language>
    <item>
      <title>Saving a 1950s Artificial Language for the Age of Artificial Intelligence</title>
      <dc:creator>torrua</dc:creator>
      <pubDate>Thu, 01 Oct 2026 18:59:38 +0000</pubDate>
      <link>https://dev.to/torrua/building-lod-manager-an-open-source-desktop-dictionary-editor-with-tauri-v2-svelte-5-and-rust-4h5m</link>
      <guid>https://dev.to/torrua/building-lod-manager-an-open-source-desktop-dictionary-editor-with-tauri-v2-svelte-5-and-rust-4h5m</guid>
      <description>&lt;p&gt;&lt;em&gt;Why would anyone rescue a human language designed on punch cards — in the era of neural networks?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article is submitted for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;In 1955, a sociologist and science fiction writer named Dr. James Cooke Brown set out to answer a question that philosophers and linguists had debated for centuries: &lt;em&gt;does the language you speak shape the way you think?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To test this — the Sapir-Whorf hypothesis — he didn't study existing languages. He built a new one from scratch: &lt;strong&gt;Loglan&lt;/strong&gt; (Logical Language).&lt;/p&gt;

&lt;p&gt;The goal was ambitious: create a human-speakable language based on &lt;strong&gt;first-order predicate logic&lt;/strong&gt;, free of syntactic ambiguity. Every grammatical sentence in Loglan has exactly one parse tree.&lt;/p&gt;

&lt;p&gt;Decades later, a dedicated community of researchers, linguists, and hobbyists still speaks and expands Loglan. (Its better-known descendant, &lt;strong&gt;Lojban&lt;/strong&gt;, forked in the 1990s and carries a different grammar — but the original Loglan corpus remains the older and more tightly formalized of the two.) Until recently, the master dictionary — the Loglan Online Dictionary, or &lt;strong&gt;LOD&lt;/strong&gt; — lived in legacy &lt;code&gt;@&lt;/code&gt;-delimited flat text files (&lt;code&gt;Words.txt&lt;/code&gt;, &lt;code&gt;WordDefinition.txt&lt;/code&gt;, &lt;code&gt;LexEvent.txt&lt;/code&gt;) managed by scripts from the 1990s.&lt;/p&gt;

&lt;p&gt;When the tools keeping a niche language accessible break down, the language fades.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;&lt;a href="https://github.com/torrua/LOD_manager" rel="noopener noreferrer"&gt;LOD Manager&lt;/a&gt;&lt;/strong&gt;: a cross-platform, local-first desktop and mobile dictionary editor powered by Tauri v2, Svelte 5, and Rust.&lt;/p&gt;

&lt;p&gt;What I didn't expect was the realization that came along the way: &lt;strong&gt;Artificial Languages and Artificial Intelligence have been working on the same problem — from opposite ends.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Artificial Language &amp;amp; Artificial Intelligence: Two Sides of the Same Coin
&lt;/h2&gt;

&lt;p&gt;We talk endlessly about Artificial Intelligence but rarely about Artificial Languages. Yet both were born from the same mid-20th-century intellectual explosion that gave us cybernetics, information theory, and cognitive science — and they clashed almost immediately.&lt;/p&gt;

&lt;p&gt;In 1957, two years after Brown began Loglan, Noam Chomsky published &lt;em&gt;Syntactic Structures&lt;/em&gt; and wrote a critical review challenging whether a formal grammar could fully capture a human language. It was a direct polemic about the limits of formalization in language — the exact same debate that plays out today when we ask whether structured output formats can make LLMs reason reliably.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Trap of Ambiguity
&lt;/h3&gt;

&lt;p&gt;Human languages are messy. The Winograd schema (&lt;em&gt;"The trophy didn't fit in the suitcase because it was too big"&lt;/em&gt;) exists because natural language relies on world knowledge to resolve syntax. LLMs spend billions of parameters on disambiguation that a well-designed formal language would never need.&lt;/p&gt;

&lt;p&gt;Loglan was engineered to eliminate this. Its grammar was designed to be machine-checkable — and by the 1980s it had been validated with LALR parsers to confirm &lt;strong&gt;zero syntactic ambiguity&lt;/strong&gt;. Here is what that means in practice:&lt;/p&gt;

&lt;p&gt;English: &lt;em&gt;"Pretty little girls' school."&lt;/em&gt;&lt;br&gt;
How many ways can you parse this? At least five: a pretty school for little girls, a small school for pretty girls, a pretty and small school for girls, a school for girls who are pretty and little, and more. English grammar gives you no way to tell which one the speaker meant.&lt;/p&gt;

&lt;p&gt;In Loglan, each of these meanings is a &lt;strong&gt;different sentence&lt;/strong&gt;. The grammar particles (&lt;code&gt;ge&lt;/code&gt;, &lt;code&gt;ci&lt;/code&gt;, and others) force the speaker to specify exactly what modifies what. You can't produce the phrase without choosing one parse — ambiguity literally cannot arise. (The &lt;a href="https://loglan.org" rel="noopener noreferrer"&gt;Loglan Institute&lt;/a&gt; uses this exact example as a demonstration of the language's core design principle.)&lt;/p&gt;

&lt;p&gt;This is why a Loglan corpus is structurally interesting for AI evaluation: every sentence is its own ground truth. No human annotation needed to establish the "correct" parse — the grammar guarantees it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Sapir-Whorf for Machines
&lt;/h3&gt;

&lt;p&gt;Brown created Loglan to test whether human thought could be freed from the irrationalities of natural language.&lt;/p&gt;

&lt;p&gt;Today, we're asking the same question of AI: &lt;strong&gt;does representation shape reasoning?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When an LLM outputs free-form prose, it hallucinates.&lt;/li&gt;
&lt;li&gt;When we constrain it to structured schemas — JSON, DSLs, typed tool calls — reliability goes up dramatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In hindsight, Loglan was asking the same question that prompt engineering asks today: can you improve thinking by improving the language you think in? Brown just asked it seventy years earlier, and his "prompt format" was an entire human-speakable language.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Neuro-Symbolic Opportunity
&lt;/h3&gt;

&lt;p&gt;AI research is moving from pure statistical pattern-matching toward &lt;strong&gt;neuro-symbolic&lt;/strong&gt; approaches — combining neural networks with symbolic logic. To evaluate whether a model genuinely reasons or merely pattern-matches against natural language noise, you need test corpora with deterministic parses and explicit semantic categories.&lt;/p&gt;

&lt;p&gt;The Loglan dictionary already has these properties built in: every word carries a type classification (primitive, complex, affix, little word), every definition tags keywords with explicit &lt;code&gt;«keyword»&lt;/code&gt; markers, and the predicate structure assigns fixed argument slots (&lt;code&gt;x1 gives x2 to x3&lt;/code&gt;). These aren't annotations I added — they're the native structure of the language, designed decades before anyone imagined benchmarking neural networks.&lt;/p&gt;

&lt;p&gt;The catch is that none of this is useful while it's trapped in &lt;code&gt;@&lt;/code&gt;-delimited text files from the 1990s. It needs to be relational, searchable, and open. That's what LOD Manager exists to do.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Desktop, Not Web?
&lt;/h2&gt;

&lt;p&gt;Before choosing a stack, I tried a few other paths. A &lt;strong&gt;PWA&lt;/strong&gt; couldn't open external &lt;code&gt;.db&lt;/code&gt; files from disk. &lt;strong&gt;IndexedDB&lt;/strong&gt; can't work with arbitrary SQLite databases that maintainers bring. &lt;strong&gt;Electron&lt;/strong&gt; worked, but resource usage was absurd for what is essentially a search-and-edit interface over a 2MB database. I briefly considered a pure CLI tool, but dictionary browsing needs a visual UI — you're constantly cross-referencing words, affixes, and etymologies.&lt;/p&gt;

&lt;p&gt;That left a native-shell approach. The constraints were clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Offline-first.&lt;/strong&gt; Linguists and field researchers work on planes, in libraries, off the grid. The dictionary must work with no network. On my mid-range laptop (Ryzen 5, 16GB), cold start is ~180ms; warm start is under 100ms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data ownership.&lt;/strong&gt; Maintainers need to open arbitrary &lt;code&gt;.db&lt;/code&gt; files, import legacy text archives, and export standalone HTML dictionaries with one click.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightweight.&lt;/strong&gt; The production binary is 8MB. Idle RSS is ~45MB. Compare that to a typical Electron app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This led to &lt;strong&gt;Tauri v2&lt;/strong&gt; + &lt;strong&gt;Rust&lt;/strong&gt; + &lt;strong&gt;SQLite (FTS5)&lt;/strong&gt; + &lt;strong&gt;Svelte 5&lt;/strong&gt;. &lt;a href="https://dev.to/lior_cyanote/i-built-a-local-first-productivity-app-with-rust-and-tauri-d43"&gt;Several&lt;/a&gt; &lt;a href="https://dev.to/hiyoyok/tauri-v2-vs-electron-after-6-months-of-real-development-my-honest-take-2ic0"&gt;developers&lt;/a&gt; on DEV have written about the same Tauri-over-Electron calculus — the tradeoffs are real, but for a data-heavy offline tool the choice was clear.&lt;/p&gt;


&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────┐
│              Frontend (Svelte 5 + TS)                │
│ Virtualized Word List · Custom Chips · Reactive Search│
└──────────────────────────┬───────────────────────────┘
                           │ Tauri IPC (30 typed commands)
┌──────────────────────────▼───────────────────────────┐
│                  Rust Backend (Tauri v2)              │
│ State Management · rusqlite · HTML Exporter · FTS Sync│
└──────────────────────────┬───────────────────────────┘
                           │
┌──────────────────────────▼───────────────────────────┐
│                Local SQLite Database                 │
│  Relational Schema + FTS5 Full-Text Virtual Tables   │
└──────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5gtn0kzyjk9nodyffe8k.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5gtn0kzyjk9nodyffe8k.png" alt="LOD Manager desktop — word detail view with sidebar search, type filters, definitions with argument slots, and etymology chips" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  SQLite FTS5: Four Ways to Search
&lt;/h3&gt;

&lt;p&gt;Loglan lexicography is bidirectional: Loglan→English and English→Loglan. For English full-text search, &lt;code&gt;LIKE '%query%'&lt;/code&gt; degraded fast over tens of thousands of definitions. I built on SQLite's &lt;strong&gt;FTS5&lt;/strong&gt; with the &lt;code&gt;unicode61&lt;/code&gt; tokenizer, using a &lt;code&gt;content&lt;/code&gt;-synced table so that inserts and deletes go through the main &lt;code&gt;definitions&lt;/code&gt; table and triggers keep the FTS index in lockstep:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;VIRTUAL&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;def_fts&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="n"&gt;fts5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'definitions'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tokenize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'unicode61 remove_diacritics 1'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This became a 4-mode engine: &lt;strong&gt;FTS5 full-body&lt;/strong&gt; (ranked BM25 with snippets), &lt;strong&gt;FTS5 keywords-only&lt;/strong&gt; (searching &lt;code&gt;«keyword»&lt;/code&gt; tags), &lt;strong&gt;LIKE fallback&lt;/strong&gt; (for external databases without FTS tables), and &lt;strong&gt;prefix/wildcard filtering&lt;/strong&gt; across affixes and compounds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Svelte 5 Runes
&lt;/h3&gt;

&lt;p&gt;Migrating to Svelte 5 Runes (&lt;code&gt;$state&lt;/code&gt;, &lt;code&gt;$derived&lt;/code&gt;, &lt;code&gt;$effect&lt;/code&gt;) was the biggest quality-of-life upgrade in the project. The old store-based reactivity caused cascading re-renders when filtering 10,000+ words. With Runes, I deleted about 40% of my reactive store code and nothing broke. That's when I knew the migration was worth it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$state&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;WordSummary&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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;searchQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$state&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;selectedType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$state&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;visibleWords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;typeMatches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;selectedType&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;selectedType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;typeMatches&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paired with a virtualized sidebar renderer (28px row height), scrolling through the full lexicon stays at 60 FPS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Typed IPC
&lt;/h3&gt;

&lt;p&gt;All 30 Tauri commands are typed end-to-end. If a Rust struct in &lt;code&gt;models.rs&lt;/code&gt; drifts from the TypeScript interface in &lt;code&gt;types.ts&lt;/code&gt;, the compiler catches it before any user does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[tauri::command]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_word&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AppState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WordDetail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;with_db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;db&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_word&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&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;h2&gt;
  
  
  Hard Lessons
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Foreign keys without cascade.&lt;/strong&gt; The legacy Loglan schema had M2M tables (&lt;code&gt;connect_words&lt;/code&gt;, &lt;code&gt;connect_authors&lt;/code&gt;, &lt;code&gt;connect_keys&lt;/code&gt;) generated without &lt;code&gt;ON DELETE CASCADE&lt;/code&gt;. I enforce &lt;code&gt;PRAGMA foreign_keys = ON&lt;/code&gt; in LOD Manager — so the first time I tried to delete a word, SQLite threw a constraint error. I spent two evenings tracing foreign key violations before realizing every delete needed explicit child-row cleanup in a transaction block. The fix was straightforward once I understood the schema; finding it was not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Android content URIs.&lt;/strong&gt; On desktop, opening a database is opening a file path. On Android, the user picks a file and gets a scoped &lt;code&gt;content://&lt;/code&gt; URI — which SQLite refuses to open directly. I had to write a stream-copy bridge that reads the URI through Android's content resolver, writes to a temporary app-local path, and opens &lt;em&gt;that&lt;/em&gt;. It took a full weekend to get right, including handling permission revocations on app restart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incremental FTS sync.&lt;/strong&gt; When a maintainer edits a definition through the UI, the FTS5 index must stay current. My first attempt — rebuild the entire index on every save — worked until someone edited 30 definitions in a row and each save took 400ms. I moved to trigger-based incremental sync (delete old row, insert new row) which brought per-save cost under 5ms. Small table, big difference in perceived responsiveness.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Build
&lt;/h2&gt;

&lt;p&gt;When Brown and his team engineered Loglan in the 1950s–70s, they were working with the sharpest tools available: mainframes, punch cards, and — after Chomsky's &lt;em&gt;Syntactic Structures&lt;/em&gt; appeared in 1957 — a brand-new theoretical framework for formal grammars. By the 1980s they were feeding Loglan into LALR parsers on Unix workstations. Each decade, the best available technology was pointed at the same question: &lt;em&gt;can language be made precise enough to change how we think?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Seven decades later, I reach for Rust, Tauri, and Svelte. The tools couldn't look more different. But the question hasn't changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technologies change. Our fascination with the mind simply takes different forms.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In 1955 it was an artificial language. In 2026 it is artificial intelligence. The medium shifts; the curiosity endures. And building open tools that keep these experiments alive — that is the work worth doing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Explore &amp;amp; Contribute
&lt;/h2&gt;

&lt;p&gt;LOD Manager is MIT-licensed and open source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/torrua/LOD_manager" rel="noopener noreferrer"&gt;github.com/torrua/LOD_manager&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🛠️ &lt;strong&gt;Stack:&lt;/strong&gt; Tauri v2, Rust (2024 edition), Svelte 5, TypeScript, SQLite FTS5&lt;/li&gt;
&lt;li&gt;🐛 &lt;strong&gt;Good first issues:&lt;/strong&gt; &lt;a href="https://github.com/torrua/LOD_manager/issues" rel="noopener noreferrer"&gt;open issues&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're interested in computational linguistics, building local-first apps, or want to help test on Linux or Android — issues and PRs are welcome.&lt;/p&gt;

&lt;p&gt;What do you think about the relationship between constructed languages and AI? I'd love to hear your perspective in the comments.&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>ai</category>
      <category>rust</category>
      <category>svelte</category>
    </item>
  </channel>
</rss>
