<?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>Forem: Christian Himpe</title>
    <description>The latest articles on Forem by Christian Himpe (@gramian).</description>
    <link>https://forem.com/gramian</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%2F362246%2F5b69e52c-327a-4289-8c69-985937ba99d4.png</url>
      <title>Forem: Christian Himpe</title>
      <link>https://forem.com/gramian</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gramian"/>
    <language>en</language>
    <item>
      <title>DatAasee 0.5 Released!</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Thu, 13 Nov 2025 15:48:16 +0000</pubDate>
      <link>https://forem.com/gramian/dataasee-05-released-1mcg</link>
      <guid>https://forem.com/gramian/dataasee-05-released-1mcg</guid>
      <description>&lt;p&gt;DatAasee - A Metadata-Lake for Libraries - Version 0.5 has been released:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ulbmuenster/dataasee" rel="noopener noreferrer"&gt;https://github.com/ulbmuenster/dataasee&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using declarative programming all the way down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://github.com/compose-spec/compose-spec" rel="noopener noreferrer"&gt;Compose&lt;/a&gt;-based web service,&lt;/li&gt;
&lt;li&gt;combining the &lt;a href="https://github.com/ArcadeData/arcadedb" rel="noopener noreferrer"&gt;ArcadeDB&lt;/a&gt; database,&lt;/li&gt;
&lt;li&gt;with a &lt;a href="https://github.com/redpanda-data/benthos" rel="noopener noreferrer"&gt;Benthos&lt;/a&gt; back-end,&lt;/li&gt;
&lt;li&gt;and a &lt;a href="https://github.com/lowdefy/lowdefy" rel="noopener noreferrer"&gt;Lowdefy&lt;/a&gt; front-end.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>metadata</category>
      <category>datalake</category>
      <category>declarative</category>
      <category>programming</category>
    </item>
    <item>
      <title>DatAasee - A Metadata-Lake</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Tue, 06 May 2025 15:42:54 +0000</pubDate>
      <link>https://forem.com/gramian/dataasee-a-metadata-lake-jb8</link>
      <guid>https://forem.com/gramian/dataasee-a-metadata-lake-jb8</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/ulbmuenster/dataasee" rel="noopener noreferrer"&gt;DatAasee&lt;/a&gt; is an open-source metadata-lake, functioning as a metadata aggregator of distributed data-sources in libraries. It instantiates a &lt;a href="https://en.wikipedia.org/wiki/Dataspace" rel="noopener noreferrer"&gt;data space&lt;/a&gt; and provides a &lt;a href="https://www.go-fair.org/fair-principles/" rel="noopener noreferrer"&gt;FAIR&lt;/a&gt;-compliant metadata-layer for repositories. Its data architecture is a data-lake which is its own metadata catalog, hence a metadata-lake, with an underlying graph data model.&lt;/p&gt;

&lt;p&gt;Internally, &lt;strong&gt;DatAasee&lt;/strong&gt; is realized as a three tier software architecture, where each tier is encapsulated in its own container. The inner data-tier is a multi-model NoSQL database &lt;a href="https://arcadedb.com" rel="noopener noreferrer"&gt;ArcadeDB&lt;/a&gt;. The middle logic-tier is an (HTTP-JSON-REST) API-server and semantic-layer around the database realized via &lt;a href="https://docs.redpanda.com/redpanda-connect/home/" rel="noopener noreferrer"&gt;Connect&lt;/a&gt; (aka Benthos). The outer presentation-layer uses &lt;a href="https://lowdefy.com" rel="noopener noreferrer"&gt;Lowdefy&lt;/a&gt; as a prototype frontend which exclusively uses the API. This multi-container application is deployed and orchestrated via &lt;a href="https://compose-spec.io" rel="noopener noreferrer"&gt;Compose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For in-depth explanations, see the open-access white paper: "&lt;a href="https://arxiv.org/abs/2409.05512" rel="noopener noreferrer"&gt;DatAasee -- A Metadata-Lake as Metadata Catalog for a Virtual Data-Lake&lt;/a&gt;".&lt;/p&gt;

</description>
      <category>dataops</category>
      <category>dataengineering</category>
      <category>datalake</category>
      <category>dataspace</category>
    </item>
    <item>
      <title>Scheming About Clojure</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Wed, 13 Nov 2024 20:53:52 +0000</pubDate>
      <link>https://forem.com/gramian/scheming-about-clojure-133n</link>
      <guid>https://forem.com/gramian/scheming-about-clojure-133n</guid>
      <description>&lt;p&gt;&lt;a href="https://clojure.org/" rel="noopener noreferrer"&gt;Clojure&lt;/a&gt; is a LISP for the Java Virtual Machine (JVM). As a schemer, I wondered if I should give Clojure a go professionally. After all, I enjoy &lt;a href="https://www.youtube.com/watch?v=SxdOUGdseq4" rel="noopener noreferrer"&gt;Rich Hickey's talks&lt;/a&gt; and even &lt;a href="https://blog.cleancoder.com/uncle-bob/2019/08/22/WhyClojure.html" rel="noopener noreferrer"&gt;Uncle Bob&lt;/a&gt; is a Clojure fan. So I considered strength and weaknesses from my point of view:&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;S-Expressions&lt;/li&gt;
&lt;li&gt;Makes functional programming easy&lt;/li&gt;
&lt;li&gt;Schemy naming with &lt;code&gt;?&lt;/code&gt; and &lt;code&gt;!&lt;/code&gt; suffixes&lt;/li&gt;
&lt;li&gt;Integrated testing framework&lt;/li&gt;
&lt;li&gt;Platform independence due to JVM&lt;/li&gt;
&lt;li&gt;Simple Java interoperability&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.google.de/books/edition/Quick_Clojure/HXsyDwAAQBAJ?hl=en&amp;amp;gbpv=1&amp;amp;pg=PA19" rel="noopener noreferrer"&gt;Clojure map type corresponds to JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Web-server abstraction with extensions (&lt;a href="https://github.com/ring-clojure/ring" rel="noopener noreferrer"&gt;Ring&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Dedicated Ubuntu-based &lt;a href="https://hub.docker.com/_/clojure" rel="noopener noreferrer"&gt;Docker image&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cons
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Too many core functions&lt;/li&gt;
&lt;li&gt;Too many concurrency concepts&lt;/li&gt;
&lt;li&gt;Having collection functions and the sequence API is confusing&lt;/li&gt;
&lt;li&gt;Keywords feels unnecessary, given symbols&lt;/li&gt;
&lt;li&gt;Unwieldy default project structure&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://leiningen.org" rel="noopener noreferrer"&gt;Leiningen&lt;/a&gt; feels forced upon you&lt;/li&gt;
&lt;li&gt;&lt;a href="https://curiousprogrammer.net/posts/2023-09-18_run-clojure-repl-with-plain-java" rel="noopener noreferrer"&gt;Clojure is not just a single jar (anymore)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;No integrated JSON parser&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Insight
&lt;/h2&gt;

&lt;p&gt;Clojure seems good enough. It is not flawless and somewhat overloaded, but far, far ahead of Javascript, Python, Go, or Rust. Of course, I would always prefer &lt;a href="https://call-cc.org" rel="noopener noreferrer"&gt;CHICKEN Scheme&lt;/a&gt; for any passion project. But in an environment that already runs databases written in Java, the JVM has street cred, and a large community hints at sustainability, Clojure presents itself as well balanced in novelty and stability. All in all, Clojure seems to be the enterprise Lisp.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://clojure.org/reference/lisps" rel="noopener noreferrer"&gt;https://clojure.org/reference/lisps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.more-magic.net/posts/thoughts-on-clojure.html" rel="noopener noreferrer"&gt;https://www.more-magic.net/posts/thoughts-on-clojure.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.packtpub.com/en-us/product/the-clojure-workshop-9781838825485" rel="noopener noreferrer"&gt;The Clojure Workshop&lt;/a&gt; (Book)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>clojure</category>
      <category>programming</category>
      <category>java</category>
      <category>lisp</category>
    </item>
    <item>
      <title>One Minute: DatAasee</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Tue, 10 Sep 2024 15:43:52 +0000</pubDate>
      <link>https://forem.com/gramian/one-minute-dataasee-2fmn</link>
      <guid>https://forem.com/gramian/one-minute-dataasee-2fmn</guid>
      <description>&lt;p&gt;&lt;strong&gt;DatAasee&lt;/strong&gt; is a metadata-lake to aggregate and centralize bibliographic and research-data metadata from distributed data and metadata sources to improve discoverability and &lt;a href="https://www.go-fair.org/fair-principles/" rel="noopener noreferrer"&gt;FAIR&lt;/a&gt;ness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt; &lt;a href="https://en.wikipedia.org/wiki/REST" rel="noopener noreferrer"&gt;REST&lt;/a&gt;-like &lt;a href="https://en.wikipedia.org/wiki/Command_Query_Responsibility_Segregation" rel="noopener noreferrer"&gt;CQRS&lt;/a&gt; HTTP-API, Faceted Search, Full-text Search&lt;br&gt;
&lt;strong&gt;Interface:&lt;/strong&gt; &lt;a href="https://www.openapis.org/" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt;, &lt;a href="https://www.json.org" rel="noopener noreferrer"&gt;JSON&lt;/a&gt;, &lt;a href="https://jsonapi.org/" rel="noopener noreferrer"&gt;JSON API&lt;/a&gt;, &lt;a href="https://json-schema.org/" rel="noopener noreferrer"&gt;JSON Schema&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Query Languages:&lt;/strong&gt; &lt;a href="https://docs.arcadedb.com/#SQL" rel="noopener noreferrer"&gt;SQL dialect&lt;/a&gt;, &lt;a href="https://neo4j.com/docs/cypher-manual/current/introduction/" rel="noopener noreferrer"&gt;Cypher&lt;/a&gt;, &lt;a href="https://tinkerpop.apache.org/gremlin.html" rel="noopener noreferrer"&gt;Gremlin&lt;/a&gt;, &lt;a href="https://www.mongodb.com/docs/manual/tutorial/query-documents/" rel="noopener noreferrer"&gt;MQL&lt;/a&gt;, &lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Ingest Protocols:&lt;/strong&gt; &lt;a href="https://www.openarchives.org/pmh" rel="noopener noreferrer"&gt;OAI-PMH&lt;/a&gt;, &lt;a href="https://docs.aws.amazon.com/s3" rel="noopener noreferrer"&gt;S3&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Ingest Encoding:&lt;/strong&gt; &lt;a href="https://www.w3.org/XML/" rel="noopener noreferrer"&gt;XML&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Ingest Formats:&lt;/strong&gt; &lt;a href="https://datacite.org/" rel="noopener noreferrer"&gt;DataCite&lt;/a&gt;, &lt;a href="https://www.dublincore.org/" rel="noopener noreferrer"&gt;DublinCore&lt;/a&gt;, &lt;a href="https://www.loc.gov/standards/marcxml" rel="noopener noreferrer"&gt;MARC&lt;/a&gt;, &lt;a href="https://www.loc.gov/standards/mods" rel="noopener noreferrer"&gt;MODS&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Deployment:&lt;/strong&gt; &lt;a href="https://compose-spec.io/" rel="noopener noreferrer"&gt;Compose&lt;/a&gt;, &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker-Compose&lt;/a&gt;, &lt;a href="https://github.com/containers/podman-compose" rel="noopener noreferrer"&gt;Podman-Compose&lt;/a&gt;, K8s (via &lt;a href="https://kompose.io/" rel="noopener noreferrer"&gt;Kompose&lt;/a&gt;)&lt;br&gt;
&lt;strong&gt;Components:&lt;/strong&gt; &lt;a href="https://arcadedb.com/" rel="noopener noreferrer"&gt;ArcadeDB&lt;/a&gt;, &lt;a href="https://www.redpanda.com/connect" rel="noopener noreferrer"&gt;Connect&lt;/a&gt;, &lt;a href="https://www.lowdefy.com/" rel="noopener noreferrer"&gt;Lowdefy&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; &lt;a href="https://spdx.org/licenses/MIT.html" rel="noopener noreferrer"&gt;MIT&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://ulbmuenster.github.io/dataasee" rel="noopener noreferrer"&gt;https://ulbmuenster.github.io/dataasee&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/ulbmuenster/dataasee" rel="noopener noreferrer"&gt;https://github.com/ulbmuenster/dataasee&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Companion Paper&lt;/strong&gt;: &lt;a href="https://arxiv.org/abs/2409.05512" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2409.05512&lt;/a&gt;&lt;/p&gt;

</description>
      <category>oneminute</category>
      <category>dataengineering</category>
      <category>database</category>
      <category>metadatalake</category>
    </item>
    <item>
      <title>One Minute: DuckDB</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Tue, 20 Aug 2024 17:16:46 +0000</pubDate>
      <link>https://forem.com/gramian/one-minute-duckdb-18on</link>
      <guid>https://forem.com/gramian/one-minute-duckdb-18on</guid>
      <description>&lt;p&gt;&lt;strong&gt;DuckDB&lt;/strong&gt; is an open-source, in-memory, column-oriented relational database management system inspired by SQLite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Model:&lt;/strong&gt; Relational&lt;br&gt;
&lt;strong&gt;Interfaces:&lt;/strong&gt; C, C++, Go, Java, Julia, Node, Python, R, Rust, Swift, WASM, ADBC, ODBC&lt;br&gt;
&lt;strong&gt;Query Language:&lt;/strong&gt; SQL super-set&lt;br&gt;
&lt;strong&gt;Features:&lt;/strong&gt; Console, &lt;a href="https://en.wikipedia.org/wiki/ACID" rel="noopener noreferrer"&gt;ACID&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Programming Language:&lt;/strong&gt; C++&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; &lt;a href="https://spdx.org/licenses/MIT.html" rel="noopener noreferrer"&gt;MIT&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://duckdb.org" rel="noopener noreferrer"&gt;https://duckdb.org&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://duckdb.org/docs" rel="noopener noreferrer"&gt;https://duckdb.org/docs&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/duckdb/duckdb" rel="noopener noreferrer"&gt;https://github.com/duckdb/duckdb&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Mastodon:&lt;/strong&gt; &lt;a href="https://mastodon.social/@duckdb" rel="noopener noreferrer"&gt;https://mastodon.social/@duckdb&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Twitter:&lt;/strong&gt; &lt;a href="https://twitter.com/duckdb" rel="noopener noreferrer"&gt;https://twitter.com/duckdb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database of Databases:&lt;/strong&gt; &lt;a href="https://dbdb.io/db/duckdb" rel="noopener noreferrer"&gt;https://dbdb.io/db/duckdb&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;DB-Engines:&lt;/strong&gt; &lt;a href="https://db-engines.com/en/system/DuckDB" rel="noopener noreferrer"&gt;https://db-engines.com/en/system/DuckDB&lt;/a&gt;&lt;/p&gt;

</description>
      <category>oneminute</category>
      <category>database</category>
      <category>sql</category>
      <category>duckdb</category>
    </item>
    <item>
      <title>One Minute: Compose</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Sat, 30 Mar 2024 18:51:46 +0000</pubDate>
      <link>https://forem.com/gramian/one-minute-compose-lkj</link>
      <guid>https://forem.com/gramian/one-minute-compose-lkj</guid>
      <description>&lt;p&gt;&lt;strong&gt;Compose&lt;/strong&gt; is a single-host container orchestrator for single and multi-container applications.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specification: &lt;a href="https://compose-spec.io" rel="noopener noreferrer"&gt;https://compose-spec.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Definition: &lt;a href="https://docs.docker.com/compose/compose-file/" rel="noopener noreferrer"&gt;Compose File&lt;/a&gt; (YAML)&lt;/li&gt;
&lt;li&gt;Elements:

&lt;ul&gt;
&lt;li&gt;Services,&lt;/li&gt;
&lt;li&gt;Network,&lt;/li&gt;
&lt;li&gt;Volumes,&lt;/li&gt;
&lt;li&gt;Configs,&lt;/li&gt;
&lt;li&gt;Secrets&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Supports:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/compose/environment-variables/env-file/" rel="noopener noreferrer"&gt;&lt;code&gt;.env&lt;/code&gt; files&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/compose/compose-file/12-interpolation/" rel="noopener noreferrer"&gt;Interpolation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Features:

&lt;ul&gt;
&lt;li&gt;Dependency resolution,&lt;/li&gt;
&lt;li&gt;Resource limits (CPU &amp;amp; RAM),&lt;/li&gt;
&lt;li&gt;Remote deploy (SSH)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Compatibility:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://podman-desktop.io/docs/compose/setting-up-compose" rel="noopener noreferrer"&gt;Podman (via &lt;code&gt;docker-compose&lt;/code&gt;)&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/containers/podman-compose" rel="noopener noreferrer"&gt;Podman (via &lt;code&gt;podman-compose&lt;/code&gt;)&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kompose.io" rel="noopener noreferrer"&gt;Kubernetes (via &lt;code&gt;kompose&lt;/code&gt;)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>compose</category>
      <category>kubernetes</category>
      <category>podman</category>
    </item>
    <item>
      <title>My Data Engineering Library</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Tue, 19 Mar 2024 14:08:20 +0000</pubDate>
      <link>https://forem.com/gramian/my-data-engineering-library-nei</link>
      <guid>https://forem.com/gramian/my-data-engineering-library-nei</guid>
      <description>&lt;p&gt;This is neither an "Ultimate List of Data Engineering Books" nor the "Data Engineering Must-Read List", but rather my subjective recommendation for a minimal data engineering library; particularly for data engineers coming from software development, as I used to.&lt;/p&gt;

&lt;h2&gt;
  
  
  General
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reis, Housley: "&lt;a href="https://www.oreilly.com/library/view/fundamentals-of-data/9781098108298/" rel="noopener noreferrer"&gt;Fundamentals of Data Engineering&lt;/a&gt;"; Oreilly Media, 2022.

&lt;ul&gt;
&lt;li&gt;Discusses all aspects of data engineering and interlinks topics through "under currents".&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Data Modeling
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hoberman: "&lt;a href="https://technicspub.com/data-modeling-made-simple/" rel="noopener noreferrer"&gt;Data Modeling Made Simple&lt;/a&gt;"; Technics Publication, 2016.

&lt;ul&gt;
&lt;li&gt;Must-read for anybody doing data modeling.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Serra: "&lt;a href="https://www.oreilly.com/library/view/deciphering-data-architectures/9781098150754/" rel="noopener noreferrer"&gt;Deciphering Data Architecture&lt;/a&gt;"; Oreilly Media, 2024.

&lt;ul&gt;
&lt;li&gt;Description and comparison of major data architectures.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Databases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Forta: "&lt;a href="https://www.pearson.com/en-us/subject-catalog/p/sql-in-10-minutes-a-day-sams-teach-yourself/P200000000253/9780135182864" rel="noopener noreferrer"&gt;SQL in 10 Minutes&lt;/a&gt;"; Pearson, 2010.

&lt;ul&gt;
&lt;li&gt;The best minimal SQL guide I found, yet.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Kaufmann, Meier: "&lt;a href="https://link.springer.com/book/10.1007/978-3-031-27908-9" rel="noopener noreferrer"&gt;SQL and NoSQL Databases&lt;/a&gt;"; Springer, 2019.

&lt;ul&gt;
&lt;li&gt;Beyond touching all the database basics, the relational (SQL), document (Mongo) and graph model (Cypher) are recurringly contrasted. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Containerization
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Öggl, Kofler: "&lt;a href="https://www.rheinwerk-verlag.de/docker-practical-guide-for-developers-and-devops-teams/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;"; Rheinwerk Computing, 2023.

&lt;ul&gt;
&lt;li&gt;Touches on all facets of Docker alongside with typical application examples.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Gkatziouras: "&lt;a href="https://www.packtpub.com/product/a-developers-essential-guide-to-docker-compose/9781803234366" rel="noopener noreferrer"&gt;A Developer's Essential Guide to Docker Compose&lt;/a&gt;"; Packt, 2022.

&lt;ul&gt;
&lt;li&gt;In deep description of the Compose orchestrator.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Extra
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Densmore: "&lt;a href="https://www.oreilly.com/library/view/data-pipelines-pocket/9781492087823/" rel="noopener noreferrer"&gt;Data Pipelines Pocket Reference&lt;/a&gt;"; Oreilly Media, 2021.

&lt;ul&gt;
&lt;li&gt;Good example-driven overview; original source of EtLT (extract, partial transform, load, transform).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Chromatic: "&lt;a href="https://www.oreilly.com/library/view/extreme-programming-pocket/9781449399849/" rel="noopener noreferrer"&gt;Extreme Programming Pocket Guide&lt;/a&gt;"; Oreilly Media, 2003.

&lt;ul&gt;
&lt;li&gt;Extreme programming (XP) is the sanest agile method with some good sustainability practices like the 40h week.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>dataengineering</category>
      <category>agile</category>
      <category>sql</category>
      <category>docker</category>
    </item>
    <item>
      <title>One Minute: Lowdefy</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Sun, 17 Mar 2024 17:03:07 +0000</pubDate>
      <link>https://forem.com/gramian/one-minute-lowdefy-275b</link>
      <guid>https://forem.com/gramian/one-minute-lowdefy-275b</guid>
      <description>&lt;p&gt;&lt;strong&gt;Lowdefy&lt;/strong&gt; is a declarative low-code front-end framework for internal tools or &lt;a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete" rel="noopener noreferrer"&gt;CRUD&lt;/a&gt; apps defined via &lt;a href="https://yaml.org/" rel="noopener noreferrer"&gt;YAML&lt;/a&gt; or &lt;a href="https://www.json.org" rel="noopener noreferrer"&gt;JSON&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Block Types:&lt;/strong&gt; Input, Display, Container, List&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connections:&lt;/strong&gt; Redshift, S3, HTTP, ElasticSearch, Google Sheets, Knex, MariaDB, MongoDB, SQL Server, MySQL, PostgreSQL, Redis, SendGrid, SQLite, Stripe&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Features:&lt;/strong&gt; &lt;a href="https://www.ag-grid.com" rel="noopener noreferrer"&gt;AgGrid&lt;/a&gt;, &lt;a href="https://echarts.apache.org" rel="noopener noreferrer"&gt;ECharts&lt;/a&gt;, &lt;a href="https://daringfireball.net/projects/markdown/" rel="noopener noreferrer"&gt;Markdown&lt;/a&gt; (Display Blocks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modes:&lt;/strong&gt; Development, Production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Written In:&lt;/strong&gt; Javascript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layout&lt;/strong&gt;: &lt;a href="https://flexgrid.io" rel="noopener noreferrer"&gt;Flexgrid&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build On:&lt;/strong&gt; &lt;a href="https://nextjs.org" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requires:&lt;/strong&gt; &lt;a href="https://pnpm.io" rel="noopener noreferrer"&gt;PNpM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy Via:&lt;/strong&gt; Docker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License:&lt;/strong&gt; &lt;a href="https://www.apache.org/licenses/LICENSE-2.0" rel="noopener noreferrer"&gt;Apache-2.0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://lowdefy.com" rel="noopener noreferrer"&gt;https://lowdefy.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://docs.lowdefy.com/introduction" rel="noopener noreferrer"&gt;https://docs.lowdefy.com/introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/lowdefy/lowdefy" rel="noopener noreferrer"&gt;https://github.com/lowdefy/lowdefy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NPM Package:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/lowdefy" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/lowdefy&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>declarative</category>
      <category>lowcode</category>
      <category>frontend</category>
      <category>yaml</category>
    </item>
    <item>
      <title>YAML-based Database Docu</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Fri, 08 Mar 2024 13:36:15 +0000</pubDate>
      <link>https://forem.com/gramian/yaml-based-database-docu-341p</link>
      <guid>https://forem.com/gramian/yaml-based-database-docu-341p</guid>
      <description>&lt;p&gt;I recently came across the modest &lt;a href="https://github.com/aryelgois/yasql" rel="noopener noreferrer"&gt;&lt;code&gt;yasql&lt;/code&gt;&lt;/a&gt; standard to document database schemas of SQL databases, which I now use to document my rather involved &lt;a href="https://github.com/ArcadeData/arcadedb" rel="noopener noreferrer"&gt;ArcadeDB&lt;/a&gt; schema. My favorite &lt;code&gt;yasql&lt;/code&gt; features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very readable,&lt;/li&gt;
&lt;li&gt;Rich metadata fields,&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;definitions&lt;/code&gt; object for custom "macros".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a small example of a &lt;code&gt;yasql&lt;/code&gt; docu:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;DB"&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PostgreSQL"&lt;/span&gt;
  &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Project"&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.0&lt;/span&gt;
  &lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CC-BY"&lt;/span&gt;
  &lt;span class="na"&gt;authors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Me"&lt;/span&gt;

&lt;span class="na"&gt;definitions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;tiny&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;

&lt;span class="na"&gt;tables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;myTable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;myCol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VARCHAR(tiny)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  NoSQL
&lt;/h2&gt;

&lt;p&gt;Generally, NoSQL databases do not use tables to organize data. For example, ArcadeDB - a multi-model DBMS - provides a document model and a graph model. Hence, instead of a &lt;code&gt;tables&lt;/code&gt; object, I use &lt;code&gt;documents&lt;/code&gt;, &lt;a href="https://www.merriam-webster.com/dictionary/vertex" rel="noopener noreferrer"&gt;&lt;code&gt;vertexes&lt;/code&gt;&lt;/a&gt;, and &lt;code&gt;edges&lt;/code&gt; objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;documents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;myDoc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;myStr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;STRING&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(mandatory,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;notnull,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;readonly)"&lt;/span&gt;

&lt;span class="na"&gt;vertexes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;myVtx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;myNum&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LONG&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(default&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;0)"&lt;/span&gt;

&lt;span class="na"&gt;edges&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;myEdg&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;myLst&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LIST&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(max&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;255)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Alternatives
&lt;/h2&gt;

&lt;p&gt;There are (open) alternatives available which provide the benefit of visualization as entity-relationship diagram. So why not use ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;... &lt;a href="https://dbml.dbdiagram.io/docs/" rel="noopener noreferrer"&gt;DBML&lt;/a&gt; ? Because:

&lt;ul&gt;
&lt;li&gt;Column settings have to be from a very limited vocabulary.&lt;/li&gt;
&lt;li&gt;C-Style comments &lt;code&gt;//&lt;/code&gt; and &lt;code&gt;/* */&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Insufficients metadata fields (in the &lt;code&gt;project&lt;/code&gt; object).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;... &lt;a href="https://d2lang.com/tour/sql-tables/" rel="noopener noreferrer"&gt;D2 &lt;code&gt;sql_table&lt;/code&gt;&lt;/a&gt; ? Because:

&lt;ul&gt;
&lt;li&gt;Every table needs a &lt;code&gt;shape: sql_table&lt;/code&gt;, meaning a column cannot be named &lt;code&gt;shape&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;constraint&lt;/code&gt; keyword is superfluous since a constraint is already delimited by curly braces &lt;code&gt;{ }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;No metadata fields.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Visualization
&lt;/h2&gt;

&lt;p&gt;You can visualize a &lt;code&gt;yasql&lt;/code&gt;-file using &lt;a href="https://plantuml.com" rel="noopener noreferrer"&gt;PlantUML&lt;/a&gt;, which provides a &lt;a href="https://plantuml.com/yaml" rel="noopener noreferrer"&gt;YAML renderer&lt;/a&gt;. For instance, you can find the rendering of the &lt;a href="https://www.plantuml.com/plantuml/svg/ZPD1ZzCm48Nl_XLpR0Kj3ImW-O0se1ugsiAMxQ6dQkeCMqDi1zjPoBzdx6oKI0XfRvxthE_DZ9FR4D773aqjH8KHBnX82W2BXYJG7pHDJLmttlqW5IMWxwX-S3gywZ3ygjcgA2YlcwYTbL32gVnsjuM1DK4yaW_vJh5SBGiMQgt8SXpiDlTSOXklpeUK3h20aeDIK_HTMvtWsRauLnCo96hRQHjdnVof1GcFwDKL_UpjQZM7_N6xBJzkrybrgZLautYZk9d3SR-vEoRRE4kTP8RI1kjPyVxbJM8sFoLm07mzR7RbuGIVrwUidhbF9_a0vV7-otcp_tHOxzRxD46uOY7XeYqlQVPwbIWXUcqVnkHth0fUJKrvd8OSBwSVMLTom7CzF44FoC8unt0IhBU1V9WIOF7XYRlKLTR9eAx77jxapZWSG_ZjV2Lpuw9_vQfLCJoteSdBvoAhoeKe-wtcscFCAtWnUJ8s5Fh_1JKyKKBovN-7QP2l3zz1La94qwGlmb0-3lIpZcJwY5mFm3vwuFKpZsPVZpuQrzhU5a8vqxZ0t4HTJB-DIM8-3XmXRibMwGVx2m00" rel="noopener noreferrer"&gt;&lt;code&gt;yasql&lt;/code&gt; sample here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Practically, I embed a &lt;code&gt;plantuml&lt;/code&gt; verbatim block wrapping the &lt;code&gt;yasql&lt;/code&gt; YAML, in a Markdown document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```plantuml
@startyaml

# your yasql goes here ...

@endyaml
```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, using the VScode &lt;a href="https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml" rel="noopener noreferrer"&gt;PlantUML Plugin&lt;/a&gt; I can get live visualizations of my schema.&lt;/p&gt;

</description>
      <category>yaml</category>
      <category>sql</category>
      <category>nosql</category>
      <category>database</category>
    </item>
    <item>
      <title>One Minute: Lightwhale</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Sun, 28 Jan 2024 22:17:39 +0000</pubDate>
      <link>https://forem.com/gramian/one-minute-lightwhale-4il6</link>
      <guid>https://forem.com/gramian/one-minute-lightwhale-4il6</guid>
      <description>&lt;p&gt;&lt;a href="https://lightwhale.asklandd.dk" rel="noopener noreferrer"&gt;Lightwhale&lt;/a&gt; is a lightweight, immutable Linux for hosting Docker containers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Based On:&lt;/strong&gt; &lt;a href="https://buildroot.org" rel="noopener noreferrer"&gt;Buildroot&lt;/a&gt; and &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Concept:&lt;/strong&gt; Immutability and Persistence&lt;br&gt;
&lt;strong&gt;Advantages:&lt;/strong&gt; Small attack surface, no redundant apps, no installation&lt;br&gt;
&lt;strong&gt;Compatibility:&lt;/strong&gt; &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker-Compose&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Connectivity:&lt;/strong&gt; SSH&lt;br&gt;
&lt;strong&gt;Platform:&lt;/strong&gt; x86-64&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; &lt;a href="https://spdx.org/licenses/GPL-2.0-only.html" rel="noopener noreferrer"&gt;GPL-2.0&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://lightwhale.asklandd.dk" rel="noopener noreferrer"&gt;https://lightwhale.asklandd.dk&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://bitbucket.org/asklandd/lightwhale" rel="noopener noreferrer"&gt;https://bitbucket.org/asklandd/lightwhale&lt;/a&gt;&lt;/p&gt;

</description>
      <category>oneminute</category>
      <category>lightwhale</category>
      <category>docker</category>
      <category>devops</category>
    </item>
    <item>
      <title>About Functional Software Architecture</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Sun, 10 Dec 2023 13:56:34 +0000</pubDate>
      <link>https://forem.com/gramian/a-view-on-functional-software-architecture-44gm</link>
      <guid>https://forem.com/gramian/a-view-on-functional-software-architecture-44gm</guid>
      <description>&lt;p&gt;Software architecture is the practice of modularizing and organizing software development from large to small. Functional programming on the other hand is a style of programming centered around functions and, among others, concepts like &lt;a href="https://en.wikipedia.org/wiki/Pure_function" rel="noopener noreferrer"&gt;Pure functions&lt;/a&gt; or avoiding &lt;a href="https://en.wikipedia.org/wiki/State_(computer_science)" rel="noopener noreferrer"&gt;State&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Side_effect_(computer_science)" rel="noopener noreferrer"&gt;Side-Effects&lt;/a&gt; as far as possible. Functional software architecture is thus the transfer of ideas from functional programming to software architecting. In the following I will describe my point of view of such functional architecture.&lt;/p&gt;

&lt;p&gt;I note, that there are already quite a few contributions to this topic, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://increment.com/software-architecture/primer-on-functional-architecture/" rel="noopener noreferrer"&gt;https://increment.com/software-architecture/primer-on-functional-architecture/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.infoq.com/news/2023/04/late-arch-functional-programming" rel="noopener noreferrer"&gt;https://www.infoq.com/news/2023/04/late-arch-functional-programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.functional-architecture.org" rel="noopener noreferrer"&gt;https://www.functional-architecture.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;as well as various talks available on Youtube.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, I often miss the practical correspondence to functional programming. So, here is my take on functional architecture.&lt;br&gt;
To avoid a lengthy introduction to functional ideas, I assume you have some very basic understanding.&lt;/p&gt;
&lt;h2&gt;
  
  
  Software Architecture
&lt;/h2&gt;

&lt;p&gt;Every software is in essence a transformation of data, and software architecture is, to me, first of all a bird's eye view of this transformation. Thus the most basic depiction of software can be given by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inputs&lt;/li&gt;
&lt;li&gt;Outputs&lt;/li&gt;
&lt;li&gt;State&lt;/li&gt;
&lt;li&gt;Side-Effects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;which describe the core functional requirements of a software project (or component).&lt;/p&gt;
&lt;h3&gt;
  
  
  Inputs and Outputs
&lt;/h3&gt;

&lt;p&gt;Inputs control a process, while outputs result from a process. Jointly, inputs and outputs are called ports, and are specified by a:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Protocol&lt;/li&gt;
&lt;li&gt;Media type&lt;/li&gt;
&lt;li&gt;Structure&lt;/li&gt;
&lt;li&gt;Format&lt;/li&gt;
&lt;li&gt;Content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;which need to be defined on the architecture level to allow interoperability. An example for a web-service is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://httpwg.org" rel="noopener noreferrer"&gt;HTTP&lt;/a&gt; as protocol&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.json.org" rel="noopener noreferrer"&gt;JSON&lt;/a&gt; as media type&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.openapis.org" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt; to define the structure of a HTTP API&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jsonapi.org" rel="noopener noreferrer"&gt;JSON:API&lt;/a&gt; to format each message&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://json-schema.org" rel="noopener noreferrer"&gt;JSON-schema&lt;/a&gt; to define templates for request and response contents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generally, HTTP and JSON are a widespread choice, facilitating interfacing. HTTP is easily testable with a browser or standard tools like &lt;code&gt;wget&lt;/code&gt; or &lt;code&gt;curl&lt;/code&gt;. JSON is more compact than XML, not white-space sensitive like YAML, and natively parsable in Javascript, which has relevance for frontends. &lt;/p&gt;

&lt;p&gt;On a lower level, a definition could be linking type (protocol), data types (media type), header file (structure), function signatures (format), argument and return value constraints (content).&lt;/p&gt;
&lt;h3&gt;
  
  
  State vs Side-Effects
&lt;/h3&gt;

&lt;p&gt;State is a remberance of past effects, while side-effects may alter state outside the current scope. Hence, it is important if an effect affects inside or outside the project's (or component's) scope.&lt;/p&gt;
&lt;h2&gt;
  
  
  Component View
&lt;/h2&gt;

&lt;p&gt;Every non-trivial software project consists of components. Each component again is defined by a bird's eye view consisting of inputs, outputs, state, and side-effects.&lt;/p&gt;

&lt;p&gt;In my opinion, in functional architecture, functions in programming generalize to components in architecture. Hence, the characteristic of components one should aim for is purity, which means in component terms idempotence or statelessness. If a component has to carry state to be useful, such as a database, then it should be isolated from other components.&lt;/p&gt;

&lt;p&gt;To correctly architect a component's statefulness and side-effects, dependency management is paramount. This refers to dependent components as well as external dependencies, ie libraries, services, etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  Components and Containers
&lt;/h3&gt;

&lt;p&gt;As a practical approach to isolate top-level components, I think, containers (process virtualization via Docker or Podman) are particularly suitable for functional architectures, since typically containers do not retain state after restarts. Using containers to isolate components has the additional benefits of reproducible deployments, and in case of stateless containers, easier replication and scaling.&lt;/p&gt;

&lt;p&gt;Note that state, in terms of containers, can be obvious in case permanent storage in form of an external volume is needed, but state can also come in terms of temporary files or memory-based. However, state can be discardable, for example certain types of lock files are only relevant to a currently running instance.&lt;/p&gt;

&lt;p&gt;Furthermore in larger projects, components may have sub-components; here the same characterization of a sub-component, ie inputs, outputs, state, and side-effects apply, maybe not in terms of containers but in terms of libraries.&lt;/p&gt;
&lt;h3&gt;
  
  
  Side-Effect or Not?
&lt;/h3&gt;

&lt;p&gt;The more self-sufficent components are, the more care needs to be taken on their self-management. For example each component likely contributes to a log. Writing to a log can be considered state in case of an internal (local) log or a side-effect in case of a central (global) log. Importance of such an effect determines if it induces state, side-effect or can be discarded.&lt;/p&gt;

&lt;p&gt;At some level of granularity one has to disregard effects, otherwise one could consider just running the software causing heating of the environment surrounding the host system computer as a side-effect.&lt;/p&gt;
&lt;h2&gt;
  
  
  Technology Stack
&lt;/h2&gt;

&lt;p&gt;Classically, a technology stack is defined for a whole project to have some degree of homgeneity across components. Using isolated components, like containers, technology stacks can be set up individually per component while retaining homogenous ports. Individuality can refer practically to the container image, programming languages, and dependencies.&lt;/p&gt;
&lt;h3&gt;
  
  
  Functional Languages?
&lt;/h3&gt;

&lt;p&gt;A software architecture can be functional even though no functional language or functional programming paradigm is explicitly used. This is due to the focus on the ports and effects of a project and its components. However, strict discipline is required from architects with regard to those ports. Furthermore, developers need to take care, that no (non-discardable) disk- or memory-based state is introduced by using non-functional means of programming or utilized external dependencies; not to forget dependencies' dependencies.&lt;/p&gt;
&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;To use this flavor of functional architecture, internalize that its functions all the way down: A software project (main function) and each of its components correspond to functions and have inputs, outputs, state and side-effects. And while additional views maybe needed to document component interaction, these can be based off the presented component characterization.&lt;/p&gt;
&lt;h2&gt;
  
  
  Bonus: Documenting Functional Architecture
&lt;/h2&gt;

&lt;p&gt;There a various standards for documenting software architecture, like &lt;a href="https://arc42.org/" rel="noopener noreferrer"&gt;arc42&lt;/a&gt; or &lt;a href="https://c4model.com/" rel="noopener noreferrer"&gt;C4&lt;/a&gt;. While useful and somewhat well-known (there is certainly a correlation here), here architecture documentation can be further simplified, particularly due to the self-similarity of project and component. Following is a small template, that can also serve as a project's and component's README:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# {Project/Component name}&lt;/span&gt;

&lt;span class="na"&gt;What&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;One-line executive summary of project/component&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;Lead&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;Main responsible person(s) for this project/component&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;This&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;URL&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;version pinpointing project/component change&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;Repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;URL to project/component repository&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;Docu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;URL to project/component documentation&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;Ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;Summarize an input&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;output or pair of input and output&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;State&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;Summarize how if at all state is carried&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;Side Effects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;Summarize how a side effect is caused&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;Tech&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Image&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Software&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Language&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Library&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;Internal Deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;Name/URL of component dependency&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;External Deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;Name/URL to an external software depedency&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;References&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;Title/URL to a relevant reference&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note, that this file is a &lt;a href="https://daringfireball.net/projects/markdown/" rel="noopener noreferrer"&gt;Markdown&lt;/a&gt; and &lt;a href="https://yaml.org/" rel="noopener noreferrer"&gt;YAML&lt;/a&gt; file at the same time, and as such human- and machine-readable, if the fields are filled carefully.&lt;/p&gt;

&lt;p&gt;Lastly, I note using such a &lt;code&gt;README.md&lt;/code&gt; for each component (and sub-component) induces a hierarchical structure (for example of directories) in a project.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>architecture</category>
      <category>documentation</category>
      <category>programming</category>
    </item>
    <item>
      <title>One Minute: BurmillaOS</title>
      <dc:creator>Christian Himpe</dc:creator>
      <pubDate>Sun, 26 Nov 2023 11:29:42 +0000</pubDate>
      <link>https://forem.com/gramian/one-minute-burmillaos-1ki4</link>
      <guid>https://forem.com/gramian/one-minute-burmillaos-1ki4</guid>
      <description>&lt;p&gt;BurmillaOS is a minimal Linux distribution for hosting Docker containers on virtual machines. BurmillaOS is pure containers!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Based On&lt;/strong&gt;: &lt;a href="https://rancher.com/docs/os/v1.x/en/" rel="noopener noreferrer"&gt;RancherOS&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Concept&lt;/strong&gt;: &lt;a href="https://www.docker.com" rel="noopener noreferrer"&gt;Everything is Docker&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Architecture&lt;/strong&gt;: &lt;a href="https://github.com/burmilla/os/blob/master/howitworks.png" rel="noopener noreferrer"&gt;System Docker and user Docker layers&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Advantages&lt;/strong&gt;: Small attack surface, fast boot, fast container startup&lt;br&gt;
&lt;strong&gt;Compatibility&lt;/strong&gt;: &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt; (Optional)&lt;br&gt;
&lt;strong&gt;Platform&lt;/strong&gt;: x86-64&lt;br&gt;
&lt;strong&gt;License&lt;/strong&gt;: &lt;a href="https://www.apache.org/licenses/LICENSE-2.0" rel="noopener noreferrer"&gt;Apache-2.0&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://github.com/burmilla/os" rel="noopener noreferrer"&gt;https://github.com/burmilla/os&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://burmillaos.org" rel="noopener noreferrer"&gt;https://burmillaos.org&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PS&lt;/strong&gt;: Testable on Apple Silicon MacOS via &lt;a href="https://github.com/utmapp/UTM" rel="noopener noreferrer"&gt;UTM&lt;/a&gt; (Deactivate &lt;code&gt;UEFI Boot&lt;/code&gt; and use &lt;code&gt;virtio-vga&lt;/code&gt; display card emulation)&lt;/p&gt;

</description>
      <category>oneminute</category>
      <category>burmillaos</category>
      <category>docker</category>
      <category>virtualmachine</category>
    </item>
  </channel>
</rss>
