<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[anarchitekt]]></title><description><![CDATA[Architecture of  Contractualist Anarchy]]></description><link>https://risav.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1578297230642/vy1XEVBvC.png</url><title>anarchitekt</title><link>https://risav.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 13 Apr 2026 18:15:44 GMT</lastBuildDate><atom:link href="https://risav.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Mt. Kolmogorov: A Complex Climb]]></title><description><![CDATA[In the second part of this series, we will take a quick quasi-philosophical detour and think a bit more formally about the core essence of code-generation and abstractions. Then we will quickly recap what we have built so far to compose a minimal des...]]></description><link>https://risav.dev/mt-kolmogorov-a-complex-climb</link><guid isPermaLink="true">https://risav.dev/mt-kolmogorov-a-complex-climb</guid><category><![CDATA[kolmogorov-complexity]]></category><category><![CDATA[code generation]]></category><category><![CDATA[Type Theory]]></category><category><![CDATA[Code Automation]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Sat, 31 Aug 2024 11:03:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725078845862/d005048f-74a8-42f8-a624-355e5de8e30a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the second part of this series, we will take a quick quasi-philosophical detour and think a bit more formally about the core essence of code-generation and abstractions. Then we will quickly recap what we have built so far to compose a minimal description for an enterprise data CRUD+Search app.</p>
<h2 id="heading-1-kolmogorov-complexity-amp-mdl">1 Kolmogorov Complexity &amp; MDL</h2>
<p><strong>Kolmogorov complexity</strong> measures the complexity of a sequence of symbols by determining the length of the shortest computer program that can generate that sequence. It can be understood, loosely, as a measure of how efficiently a sequence can be described. The lower the Kolmogorov complexity, the simpler the sequence is to describe. Now let's think of that <em>sequence</em> as being that of our finally generated program itself. My hypothesis is that most usual software, even with 100K+ LoC, have a more minimal description that can be used as a seed to generate the rest of the code. In few bespoke cases, this minimal description for the larger program is just the project specs and C4/UML diagrams. Often times, it something much simpler than that. Borrowing from NLP and computation linguistics, we will call these <strong>minimal description</strong>s and the <strong>length</strong> of such minimal descriptions as <strong>MDL</strong>.</p>
<h2 id="heading-2-meta-kolmogorov-complexity-of-our-apps">2 (Meta) Kolmogorov Complexity of our Apps</h2>
<p><strong>Minimum description length (MDL),</strong> as a principle, states that the best model for a dataset is the one that minimizes the combined length of the model description and the data encoded using that model. This means that the MDL principle seeks to find the simplest model that can adequately explain the data.</p>
<blockquote>
<p>N.B. "Data" is code in the context of code-generators.</p>
</blockquote>
<p>MDL is thus essentially an application of the abstract concept of Kolmogorov Complexity, which on its own can only provide <a target="_blank" href="https://en.wikipedia.org/wiki/Ordinal_number#Ordinals_and_cardinals">ordinal comparisons as opposed to more precise cardinal rankings</a> from minimal description lengths.</p>
<p>In a data driven application, schema for data at rest and data over the wire dictate the kinds of services that can be possible. At the very least, the type signature, if not the behavior, of our data-facing service methods are bound to adhere to our schema's constraints and types. Given the MDL principle, and given that schema are generally ubiquitous, we can pivot to our schema to achieve the minimal length seed for our large programs. In cases where schema is implicit and needs to be inferred per collection, document, row or column, we would need the shape of some representative data records. This alone can make the seed description arbitrarily large but together with schema's constraints and guidance, the data representations can be a helpful addition to our MDL to infer data-shape-related interactions.</p>
<h2 id="heading-3-schema-and-api">3 Schema and API</h2>
<p>Say we have a database table or collection called <code>user_profile</code> and we use it to update user's preferences and profile information. How should the REST API providing interface look like? Now let's say that you have a table or collection about which you know nothing yet.</p>
<blockquote>
<p>Can you still write the REST API for data create, update, read, search, evict or delete for that entity?</p>
</blockquote>
<p>For a seasoned developer, across all major languages and frameworks, the answer is yes - in theory. Here's one example of what is possible with Prisma and its DMMF (from the last article) for a query controller:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> Query&lt;NTT <span class="hljs-keyword">extends</span> NTTKey&gt; {
    findUnique: <span class="hljs-function">(<span class="hljs-params">
        ntt: NTT,
        args: FindUniqueArgType&lt;NTT&gt;,
    </span>) =&gt;</span> ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'findUnique'</span>]&gt;;

    findFirst: <span class="hljs-function">(<span class="hljs-params">
        ntt: NTT,
        args: FindFirstArgType&lt;NTT&gt;,
    </span>) =&gt;</span> ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'findFirst'</span>]&gt;;

    findMany: <span class="hljs-function">(<span class="hljs-params">
        ntt: NTT,
        args: FindManyArgType&lt;NTT&gt;,
    </span>) =&gt;</span> ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'findMany'</span>]&gt;;

    count: <span class="hljs-function">(<span class="hljs-params">
        ntt: NTT,
        args: CountArgType&lt;NTT&gt;,
    </span>) =&gt;</span> ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'count'</span>]&gt;;

    aggregate: <span class="hljs-function">(<span class="hljs-params">
        ntt: NTT,
        args: AggregateArgType&lt;NTT&gt;,
    </span>) =&gt;</span> ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'aggregate'</span>]&gt;;

    fields: <span class="hljs-function">(<span class="hljs-params">ntt: NTTKey</span>) =&gt;</span> FieldRefType&lt;NTTKey&gt;;

    groupBy: <span class="hljs-function">(<span class="hljs-params">
        ntt: NTT,
        args: GroupByArgType&lt;NTT&gt;,
    </span>) =&gt;</span> ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'groupBy'</span>]&gt;;
}
</code></pre>
<p>This interface is meant for a controller class exposing all of the ORM capabilities for querying the database. It is not tied to any particular entity, which I am calling NTT here. Now a frontend dev can directly use prisma to compose their own queries. Should a frontend dev be unaware of prisma? In that case, the backend dev can simply write a client sdk for the the frontend engineers. The main advantage is that no matter how many entities are there, there can be just one controller. Alternatively, there can be as many CRUD controllers as there are entities but we would need <code>ts-morph</code> for that. This will be the core theme for the next article in this series.</p>
<blockquote>
<p>Can such a generalized query controller be implemented?</p>
</blockquote>
<p>Yes. Fairly trivially it seems. Here's an example:</p>
<pre><code class="lang-typescript"><span class="hljs-meta">@Controller</span>(<span class="hljs-string">'query'</span>)
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> DBQueryController <span class="hljs-keyword">implements</span> Query&lt;NTTKey&gt;
{

  <span class="hljs-meta">@Put</span>(<span class="hljs-string">':ntt/find/unique'</span>)
  findUnique&lt;NTT <span class="hljs-keyword">extends</span> NTTKey&gt;(
    <span class="hljs-meta">@Param</span>(<span class="hljs-string">'ntt'</span>) ntt: NTT,
    <span class="hljs-meta">@Body</span>() args: FindUniqArgType&lt;NTT&gt;
  ): ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'findUnique'</span>] {
    <span class="hljs-keyword">return</span> getDelegate(ntt).findUnique(args);
  }

  <span class="hljs-meta">@Put</span>(<span class="hljs-string">':ntt/find/first'</span>)
  findFirst&lt;NTT <span class="hljs-keyword">extends</span> NTTKey&gt;(
    <span class="hljs-meta">@Param</span>(<span class="hljs-string">'ntt'</span>) ntt: NTT,
    <span class="hljs-meta">@Body</span>() args: FindFirstArgType&lt;NTT&gt;
  ): ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'findFirst'</span>] {
    <span class="hljs-keyword">return</span> getDelegate(ntt).findFirst(args);
  }

  <span class="hljs-meta">@Put</span>(<span class="hljs-string">':ntt/find/many'</span>)
  findMany&lt;NTT <span class="hljs-keyword">extends</span> NTTKey&gt;(
    <span class="hljs-meta">@Param</span>(<span class="hljs-string">'ntt'</span>) ntt: NTT,
    <span class="hljs-meta">@Body</span>() args: FindManyArgType&lt;NTT&gt;
  ): ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'findMany'</span>] {
    <span class="hljs-keyword">return</span> getDelegate(ntt).findMany(args);
  }

  <span class="hljs-meta">@Put</span>(<span class="hljs-string">':ntt/count'</span>)
  count&lt;NTT <span class="hljs-keyword">extends</span> NTTKey&gt;(
    <span class="hljs-meta">@Param</span>(<span class="hljs-string">'ntt'</span>) ntt: NTT, 
    <span class="hljs-meta">@Body</span>() args: CountArgType&lt;NTT&gt;
  ): ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'count'</span>] {
    <span class="hljs-keyword">return</span> getDelegate(ntt).count(args);
  }

  <span class="hljs-meta">@Put</span>(<span class="hljs-string">':ntt/aggregate'</span>)
  aggregate&lt;NTT <span class="hljs-keyword">extends</span> NTTKey&gt;(
    <span class="hljs-meta">@Param</span>(<span class="hljs-string">'ntt'</span>) ntt: NTT,
    <span class="hljs-meta">@Body</span>() args: AggregateArgType&lt;NTT&gt;
  ): ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'aggregate'</span>] {
    <span class="hljs-keyword">return</span> getDelegate(ntt).aggregate(args);
  }

  <span class="hljs-meta">@Put</span>(<span class="hljs-string">':ntt/fields'</span>)
  fields&lt;NTT <span class="hljs-keyword">extends</span> NTTKey&gt;(<span class="hljs-meta">@Param</span>(<span class="hljs-string">'ntt'</span>) ntt: NTT): FieldRefType&lt;NTT&gt; {
    <span class="hljs-keyword">return</span> getDelegate(ntt).fields;
  }

  <span class="hljs-meta">@Put</span>(<span class="hljs-string">':ntt/groupBy'</span>)
  groupBy&lt;NTT <span class="hljs-keyword">extends</span> NTTKey&gt;(<span class="hljs-meta">@Param</span>(<span class="hljs-string">'ntt'</span>) ntt: NTT, <span class="hljs-meta">@Body</span>() args: GroupByArgType&lt;NTT&gt;): ReturnType&lt;DelegateType&lt;NTT&gt;[<span class="hljs-string">'groupBy'</span>] {
    <span class="hljs-keyword">return</span> getDelegate(ntt).groupBy(args);
  }
}
</code></pre>
<p><code>NTTKey</code> was introduced in the first part of the series and is simply a union of literal types representing all our table names. The client side SDK can essentially wrap over the Query interface shown above to make isomorphic type-safety like tRPC possible. For aiding with generics and type-safety, <code>getDelegate</code> finds us the right Prisma entity delegate needed to dispatch the JSON query to the DB query engine. Here's an example implementation of <code>getDelegate</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> <span class="hljs-keyword">type</span> { NTTKey } <span class="hljs-keyword">from</span> <span class="hljs-string">'./zen/entities-type'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> prisma = <span class="hljs-keyword">new</span> PrismaClient({
    errorFormat: <span class="hljs-string">'pretty'</span>
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> mapper = {
    Principal: prisma.principal,
    Account: prisma.account,
    Session: prisma.session,
    VerificationToken: prisma.verificationToken,
    Authenticator: prisma.authenticator,
    Payment: prisma.payment,
    Appointment: prisma.appointment,
    AppointmentType: prisma.appointmentType,
    Location: prisma.location,
    Patient: prisma.patient,
    Equipment: prisma.equipment,
    Service: prisma.service,
    Provider: prisma.provider,
    Form: prisma.form
} <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> Delegate&lt;T <span class="hljs-keyword">extends</span> NTTKey&gt; = <span class="hljs-keyword">typeof</span> mapper[T];

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getDelegate</span>&lt;<span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">NTTKey</span>&gt;(<span class="hljs-params">key: T</span>): <span class="hljs-title">Delegate</span>&lt;<span class="hljs-title">T</span>&gt; </span>{
    <span class="hljs-keyword">const</span> delegate = mapper[key];
    <span class="hljs-keyword">return</span> delegate;
}
</code></pre>
<p>Notice how the <code>Delegate</code> type is constructed using our mapping object as a compile time constant. This is a fairly advanced usage of Typescript and the explanations for how I independently discovered this pattern would be a subject for an upcoming article in this same series. Meanwhile, I would like to show how something like <code>FindUniqArgType</code> from the interface above is built using the same type-mapping technique. In this case we are mapping over an interface instead of a compile time constant:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> <span class="hljs-keyword">type</span> { Prisma } <span class="hljs-keyword">from</span> <span class="hljs-string">"@prisma/client"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-keyword">type</span> { NTTKey } <span class="hljs-keyword">from</span> <span class="hljs-string">"./entities-type"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> FindUniqueArgs {
    Principal: Prisma.PrincipalFindUniqueArgs;
    Account: Prisma.AccountFindUniqueArgs;
    Session: Prisma.SessionFindUniqueArgs;
    VerificationToken: Prisma.VerificationTokenFindUniqueArgs;
    Authenticator: Prisma.AuthenticatorFindUniqueArgs;
    Payment: Prisma.PaymentFindUniqueArgs;
    Appointment: Prisma.AppointmentFindUniqueArgs;
    AppointmentType: Prisma.AppointmentTypeFindUniqueArgs;
    Location: Prisma.LocationFindUniqueArgs;
    Patient: Prisma.PatientFindUniqueArgs;
    Equipment: Prisma.EquipmentFindUniqueArgs;
    Service: Prisma.ServiceFindUniqueArgs;
    Provider: Prisma.ProviderFindUniqueArgs;
    Form: Prisma.FormFindUniqueArgs;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> FindUniqueArgType&lt;T <span class="hljs-keyword">extends</span> NTTKey&gt; = FindUniqueArgs[T];
</code></pre>
<p>This allows us to have a single generic type (<code>FindUniqueArgType</code>) in our interface for both the controller and the client-side SDK.</p>
<p>How is this code generated and kept up to date with migrations to the database? Here's a <em>bit of</em> <code>ts-morph</code> before the next article <em>full of</em> <code>ts-morph</code>:</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createTypeFile</span>(<span class="hljs-params">
    project: Project,
    fileName: <span class="hljs-built_in">string</span>,
    interfaceName: <span class="hljs-built_in">string</span>,
    typeName: <span class="hljs-built_in">string</span>,
    properties: { name: <span class="hljs-built_in">string</span>; <span class="hljs-keyword">type</span>: <span class="hljs-built_in">string</span> }[],
</span>) </span>{
    <span class="hljs-keyword">const</span> typeFile = project.createSourceFile(<span class="hljs-string">`<span class="hljs-subst">${zenPath}</span>/<span class="hljs-subst">${fileName}</span>.ts`</span>, <span class="hljs-string">''</span>, {
        overwrite: <span class="hljs-literal">true</span>,
    });

    <span class="hljs-comment">/**
    * Adds:
    * import type { Prisma } from "@prisma/client";
    * import type { NTTKey } from "./entities-type";
    */</span>
    typeFile.addImportDeclarations(essentialImports);

    <span class="hljs-comment">/**
    * Adds 
    * export interface FindUniqueArgs {...}
    */</span>
    typeFile.addInterface({
        name: interfaceName,
        isExported: <span class="hljs-literal">true</span>,
        properties,
    });

    <span class="hljs-comment">/**
     * Adds
     * export type FindUniqueArgType&lt;T extends NTTKey&gt; = FindUniqueArgs[T];      
     */</span>
    typeFile.addTypeAlias({
        name: typeName,
        typeParameters: [<span class="hljs-string">`T extends NTTKey`</span>],
        <span class="hljs-keyword">type</span>: <span class="hljs-string">`<span class="hljs-subst">${interfaceName}</span>[T]`</span>,
        isExported: <span class="hljs-literal">true</span>,
    });

    typeFile.saveSync();
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ModelNames: <span class="hljs-built_in">string</span>[] = Prisma.dmmf.datamodel.models.map(
    <span class="hljs-function">(<span class="hljs-params">m: DMMF.Model</span>) =&gt;</span> m.name,
);

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createProperties</span>(<span class="hljs-params">suffix: <span class="hljs-built_in">string</span></span>) </span>{
    <span class="hljs-comment">// Adds interface properties to the interface e.g. </span>
    <span class="hljs-comment">// Patient: Prisma.PatientFindUniqueArgs;</span>
    <span class="hljs-keyword">return</span> ModelNames.map(<span class="hljs-function">(<span class="hljs-params">ModelName</span>) =&gt;</span> ({
        name: ModelName,
        <span class="hljs-keyword">type</span>: <span class="hljs-string">`Prisma.<span class="hljs-subst">${ModelName}</span><span class="hljs-subst">${suffix}</span>`</span>,
    }));
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createArgs</span>(<span class="hljs-params">project: Project</span>) </span>{
    createTypeFile(
        project,
        <span class="hljs-string">'findUniqueArgs'</span>,
        <span class="hljs-string">'FindUniqueArgs'</span>,
        <span class="hljs-string">'FindUniqueArgType'</span>,
        createProperties(<span class="hljs-string">'FindUniqueArgs'</span>),
    );
    <span class="hljs-comment">// Other interfaces go here in a similar way</span>
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initiateQb</span>(<span class="hljs-params"></span>): <span class="hljs-title">void</span> </span>{
    <span class="hljs-keyword">const</span> project = <span class="hljs-keyword">new</span> Project({
        tsConfigFilePath: <span class="hljs-string">'./tsconfig.json'</span>,
        skipAddingFilesFromTsConfig: <span class="hljs-literal">true</span>,
    });

    createEntities(project);
    createEntitiesType(project);
    createArgs(project);
    <span class="hljs-comment">// other generators go here</span>

    project.saveSync();
}
initiateQb();
</code></pre>
<p>In all this, we have used information from the schema's AST only. Kolmogorov complexity is an idea "so abstract that it could just as well have been a prayer" - borrowing from the <code>Foundation</code> series.</p>
<p>So far we have generated a generic controller and seen a glimpse of how code can generate more code. In the next installment in the series, we will generate a separate query controller and a mutation controller for each entity. This will help us later create a CQRS system. Having a separate controller per entity will also allow us to apply various auth(n/z) guards and administrative policies for each API endpoint. Such guards and policy-enforcers can also be created by the code-generator itself as we will soon see in future installments in this same series.</p>
]]></content:encoded></item><item><title><![CDATA[Mountains & Software: Similar Peaks]]></title><description><![CDATA[We have climbed similar mountains many times over across our usual projects. Going through these repetitions, I too have put together my toolkit for abstracting over implementation details each time, so as to scale the usual hurdles faster. This seri...]]></description><link>https://risav.dev/mountains-software-up-similar-peaks</link><guid isPermaLink="true">https://risav.dev/mountains-software-up-similar-peaks</guid><category><![CDATA[ts-morph]]></category><category><![CDATA[code generation]]></category><category><![CDATA[ast]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[rapid application development,]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Mon, 26 Aug 2024 11:42:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724662047997/932320f5-f1ef-4ee5-bf87-247847e4387a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We have climbed similar mountains many times over across our usual projects. Going through these repetitions, I too have put together my toolkit for abstracting over implementation details each time, so as to scale the usual hurdles faster. This series explores such meta-programming, special trees, and the resulting code-generators I have built for my enterprise cloud automation and CI/CD integration use-cases so far.</p>
<h2 id="heading-builders-amp-generators">Builders &amp; Generators</h2>
<p>In the world of rapid application development and 'no-code'/'low-code' app builders, code generators are a necessarily evil in the tool-chain. Code should be as DRY or repetition free as possible for maintainability. But that applies only for '<strong><em>same code</em></strong>'.</p>
<p>When it comes to <strong>'similar code'</strong>, a lot of our code can be seen as blatant repetitions of "the same kinds of things" - if not "the same things". If your framework needs a new file for a new controller, your code-generator schematics can and should be generating that controller and its test files. This is possible and quite routine with <code>nx</code>, <code>ng</code> and similar <a target="_blank" href="https://nx.dev/nx-api/angular/documents/nx-devkit-angular-devkit">cli tools</a>. What if you know that you are going to need to run that generator for each of your hundred controllers?</p>
<p>A build system that integrates code-generators can add, update or remove parts of the code-base itself. Seen this way, code-generators are the 'actors' that generate code while builders are the 'directors' that supervise the action of code-generation itself. As for knowing which controllers to generate, there usually is a signal or annotation to find out. For instance, if you are writing a new controller layer for each of your user facing entities, you can mark them as such in your database schema itself or a configuration file somewhere. Same for per-folder view files in folder-based routers used by frameworks and meta-frameworks like SvelteKit, Remix, Next, AnalogJS and Astro.</p>
<p>Prisma ORM provides a way to annotate any part of your database schema (entity model, enum, attribute) with an active comment. Any comment marked with three slashes <code>///</code> are picked up by cli-tools and libraries that tap into the capabilities of the ORM. In the case of a code-generator, this can be your own <code>ts-morph</code> scripts based on Prisma's <code>database meta model format</code> or <code>DMMF</code>.</p>
<h2 id="heading-prisma-amp-the-tree">Prisma &amp; The Tree</h2>
<p>Prisma's DMMF is an abstract syntax tree (AST) and an AST is one your best friends as a meta-programmer. Builders and generators can be guided by the AST in their internal logic. To work with your database's Prisma AST/DMMF, this is one way to expose it for programmatic use:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Prisma } <span class="hljs-keyword">from</span> <span class="hljs-string">"@prisma/client"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-keyword">type</span> { BaseDMMF } <span class="hljs-keyword">from</span> <span class="hljs-string">"@prisma/client/runtime/library"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getDMMF</span>(<span class="hljs-params"></span>): <span class="hljs-title">BaseDMMF</span> </span>{
    <span class="hljs-keyword">return</span> Prisma.dmmf;
}
</code></pre>
<p>It's a one-liner to abstract us from how Prisma decides to expose the DMMF in a future version as these parts of the library are not public or expected to stay the same. This utility can now be used every where else in our code, say, to introspect which tables are present in the database of the currently running system:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getModelNames</span>(<span class="hljs-params"></span>): <span class="hljs-title">string</span>[] </span>{
    <span class="hljs-keyword">return</span> getDMMF().datamodel.models
        .map(<span class="hljs-function"><span class="hljs-params">m</span> =&gt;</span> m.dbName ?? m.name);
}
</code></pre>
<p>Or to find metadata about the fields or columns in our table/model of interest:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getFieldMetadata</span>(<span class="hljs-params">model: <span class="hljs-built_in">string</span></span>) </span>{
    <span class="hljs-keyword">const</span> allModels = getDMMF().datamodel.models;
    <span class="hljs-keyword">const</span> selectedModel = allModels.find(<span class="hljs-function"><span class="hljs-params">mod</span> =&gt;</span> mod.dbName === model);
    <span class="hljs-keyword">if</span> (selectedModel) {
        <span class="hljs-keyword">return</span> selectedModel.fields;
    }

    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Model not found"</span>);
}
</code></pre>
<p>This isn't a particularly type-safe code code as the input is not all possible strings and the output is quite a complex type. Let's constrain the types as an exercise to get to the know the AST better and to make the above function safer to use. Let's click through the definitions in <code>@prisma/client/runtime/library.d.ts</code> as a starter:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// not exported, but you are advised to inline this in your code</span>
<span class="hljs-keyword">type</span> ReadonlyDeep_2&lt;O&gt; = {
    +<span class="hljs-keyword">readonly</span> [K <span class="hljs-keyword">in</span> keyof O]: ReadonlyDeep_2&lt;O[K]&gt;;
}

<span class="hljs-comment">// can be used as a reference for how to deal with tables (models) and columns (fields)</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> Model = ReadonlyDeep_2&lt;{
        name: <span class="hljs-built_in">string</span>;
        dbName: <span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span>;
        fields: Field[];
        uniqueFields: <span class="hljs-built_in">string</span>[][];
        uniqueIndexes: uniqueIndex[];
        documentation?: <span class="hljs-built_in">string</span>;
        primaryKey: PrimaryKey | <span class="hljs-literal">null</span>;
        isGenerated?: <span class="hljs-built_in">boolean</span>;
}&gt;;
</code></pre>
<p>At this point we can type the <code>getFieldMetadata</code> function as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getFieldMetaData</span>(<span class="hljs-params">model: <span class="hljs-built_in">string</span></span>): <span class="hljs-title">ReadonlyDeep_2</span>&lt;<span class="hljs-title">DMMF</span>.<span class="hljs-title">Field</span>[]&gt; </span>{..}
</code></pre>
<p>The <code>string</code> input type is still too wide but the output is well-typed for advanced use-cases. Wouldn't it be better if we knew our model names at the type-level, ahead of time? Thanks to the trivial <code>getModelNames</code> function, we can dump this information in a typescript file itself. That file would look something like this:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// zen/entities.const.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Principal = <span class="hljs-string">"Principal"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Account = <span class="hljs-string">"Account"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Session = <span class="hljs-string">"Session"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> VerificationToken = <span class="hljs-string">"VerificationToken"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Authenticator = <span class="hljs-string">"Authenticator"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Payment = <span class="hljs-string">"Payment"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Appointment = <span class="hljs-string">"Appointment"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> AppointmentType = <span class="hljs-string">"AppointmentType"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Location = <span class="hljs-string">"Location"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Patient = <span class="hljs-string">"Patient"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Equipment = <span class="hljs-string">"Equipment"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Service = <span class="hljs-string">"Service"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Provider = <span class="hljs-string">"Provider"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Form = <span class="hljs-string">"Form"</span> <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">The code snippets in this series are from in-production codebases from various business domains and verticals. This one above shows some tables from a clinic management app I recently built.</div>
</div>

<p>An exhaustive list of all models that need to be represented in our user interfaces can be generated like this into a file and can then be used as a type-level information in our future functions.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// zen/entities.type.ts</span>
<span class="hljs-keyword">import</span> { Principal, Account, Session, VerificationToken, Authenticator, Payment, Appointment, AppointmentType, Location, Patient, Equipment, Service, Provider, Form } <span class="hljs-keyword">from</span> <span class="hljs-string">"./entities"</span>;
<span class="hljs-keyword">const</span> Entities = {
    Principal, 
    Account, 
    Session, 
    VerificationToken, 
    Authenticator, 
    Payment, 
    Appointment, 
    AppointmentType, 
    Location, 
    Patient, 
    Equipment, 
    Service, 
    Provider, 
    Form
    <span class="hljs-comment">// 100+ similar table names</span>
} <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> EntitiesType = <span class="hljs-keyword">typeof</span> Entities;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> NTTKey = keyof EntitiesType;
</code></pre>
<p>Now we can have a much more type-safe signature for our <code>getFieldMetadata</code> function:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getFieldMetaData</span>(<span class="hljs-params">model: NTTKey</span>): <span class="hljs-title">ReadonlyDeep_2</span>&lt;<span class="hljs-title">DMMF</span>.<span class="hljs-title">Field</span>[]&gt; </span>{..}
</code></pre>
<p>A big part of code-generation - or any advanced library code - is making illegal states impossible. In this case we have ensured that we only allow valid string names for our input and a read-only <code>Field[]</code> type as our output.</p>
<h2 id="heading-ts-morph-amp-morphisms">ts-morph &amp; Morphisms</h2>
<p>In this series, <code>ts-morph</code> will be our library of choice for demonstrating the file generation part of code-gen. The above file with table names as const can be generated as follows with <code>ts-morph</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ModelNames: <span class="hljs-built_in">string</span>[] = Prisma.dmmf.datamodel.models.map(
    <span class="hljs-function">(<span class="hljs-params">m: DMMF.Model</span>) =&gt;</span> m.name,
);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">statements</span>(<span class="hljs-params">lCase = <span class="hljs-literal">false</span></span>) </span>{
    <span class="hljs-keyword">return</span> ModelNames.map(<span class="hljs-function">(<span class="hljs-params">ModelName</span>) =&gt;</span> {
        <span class="hljs-keyword">const</span> name = lCase ? firstCharLower(ModelName) : ModelName;
        <span class="hljs-keyword">return</span> {
            declarationKind: VariableDeclarationKind.Const,
            declarations: [
                {
                    name,
                    initializer: <span class="hljs-string">`"<span class="hljs-subst">${name}</span>" as const`</span>,
                },
            ],
            isExported: <span class="hljs-literal">true</span>,
        };
    });
}


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createEntities</span>(<span class="hljs-params">project: Project</span>): <span class="hljs-title">void</span> </span>{
    <span class="hljs-keyword">const</span> entitiesTsFile = project.createSourceFile(<span class="hljs-string">`<span class="hljs-subst">${zenPath}</span>/entities.ts`</span>, <span class="hljs-string">''</span>, {
        overwrite: <span class="hljs-literal">true</span>,
    });

    entitiesTsFile.addVariableStatements(statements());
    entitiesTsFile.saveSync();
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initiateQb</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> project = <span class="hljs-keyword">new</span> Project({
        tsConfigFilePath: <span class="hljs-string">'./tsconfig.json'</span>,
        skipAddingFilesFromTsConfig: <span class="hljs-literal">true</span>,
    });

    createEntities(project);
    createEntitiesType(project);
    <span class="hljs-comment">// ... other createXXX functions</span>
    project.saveSync();
}
initiateQb();
</code></pre>
<p>Generating the file <code>zen/entities.type.ts</code> from above works similarly, except for we have to import the constants from the earlier const file:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createEntitiesType</span>(<span class="hljs-params">project: Project</span>): <span class="hljs-title">void</span> </span>{
    <span class="hljs-keyword">const</span> entitiesTypeTsFile = project.createSourceFile(
        <span class="hljs-string">`<span class="hljs-subst">${zenPath}</span>/entities-type.ts`</span>,
        <span class="hljs-string">''</span>,
        {
            overwrite: <span class="hljs-literal">true</span>,
        },
    );

    entitiesTypeTsFile.addImportDeclarations([
        {
            moduleSpecifier: <span class="hljs-string">'./entities'</span>,
            namedImports: [...ModelNames],
        },
    ]);

    entitiesTypeTsFile.addVariableStatement({
        declarationKind: VariableDeclarationKind.Const,
        declarations: [
            {
                name: <span class="hljs-string">'Entities'</span>,
                initializer: <span class="hljs-string">`{<span class="hljs-subst">${ModelNames.join(<span class="hljs-string">', \n'</span>)}</span>} as const`</span>,
            },
        ],
    });

    entitiesTypeTsFile.addTypeAlias({
        name: <span class="hljs-string">'EntitiesType'</span>,
        <span class="hljs-keyword">type</span>: <span class="hljs-string">'typeof Entities'</span>,
        isExported: <span class="hljs-literal">true</span>,
    });
    entitiesTypeTsFile.addTypeAlias({
        name: <span class="hljs-string">'NTTKey'</span>,
        <span class="hljs-keyword">type</span>: <span class="hljs-string">'keyof EntitiesType'</span>,
        isExported: <span class="hljs-literal">true</span>,
    });

    entitiesTypeTsFile.saveSync();
}
</code></pre>
<p>By this point, we have an example of generated code and a solid foundation for further generating controllers, test data, CRUD UIs and even basic visualizations for each of our models.</p>
<p><code>ts-morph</code> is all it takes once we have a decent AST, like that of Prisma's DMMF. And we will be using a similar code-setup for generating most parts of a CRM that we would have manually (slowly) coded otherwise. Morphism is an abstraction over functions themselves. In our case, our basic morphisms are effects: code being written to a file. And the overall work is about composition of such morphisms.</p>
<details><summary>Here's a basic mantra for this kind of code-zen:</summary><div data-type="detailsContent">"surgically add code generators, drastically divide time-to-delivery".</div></details>]]></content:encoded></item><item><title><![CDATA[More Slide-y Thinking]]></title><description><![CDATA[Let's pick it up right where we left off last time.
A Minimal Requirement Analysis
We might need to have a lot more images in a slideshow. We will have to find ways to keep movements smooth using the appropriate CSS for the transitions and/or animati...]]></description><link>https://risav.dev/more-slide-y-thinking</link><guid isPermaLink="true">https://risav.dev/more-slide-y-thinking</guid><category><![CDATA[First Principles]]></category><category><![CDATA[Slider]]></category><category><![CDATA[Vanilla JS]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[Minimal]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Fri, 26 Apr 2024 05:18:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1714107414203/6193ce5e-30d5-435d-83ef-5683536bc675.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let's pick it up right where we left off last time.</p>
<h2 id="heading-a-minimal-requirement-analysis">A Minimal Requirement Analysis</h2>
<p>We might need to have a lot more images in a slideshow. We will have to find ways to keep movements smooth using the appropriate CSS for the transitions and/or animations.</p>
<p>In a more complex and publicly usable slider, what else would be required of the slider HTML components and the JS/CSS backing them? </p>
<p>Let's start with some laziness this time. Laziness is usually earned with hard smart work though.</p>
<p>In the context of a slider that loads many images into a browser tab, one would prefer to not load everything at once as that would require a longer wait before things are first painted, made visible, and added with interactivity.
If we have a way to check what is needed to be currently displayed, we could fetch or pre-fetch those images first or just those images exclusively.</p>
<h2 id="heading-bounds-aka-how-to-get-rect">Bounds, aka How To Get Rect</h2>
<p>It was a good idea to lookup <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect"><code>getBoundingClientRect()</code></a> on MDN as I had not been on MDN in recent months. </p>
<p>For a naive first implementation, seems like you can easily compare the rectangular dimensions of the boundary of DOM element you want to check against the height or width of the <code>window</code> or that of the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Document/documentElement"><code>document.documentElement</code></a>.</p>
<pre><code class="lang-JS"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isInViewport</span>(<span class="hljs-params">element</span>) </span>{
  <span class="hljs-keyword">const</span> rect = element.getBoundingClientRect();
  <span class="hljs-keyword">return</span> (
    rect.top &gt;= <span class="hljs-number">0</span> &amp;&amp;
    rect.left &gt;= <span class="hljs-number">0</span> &amp;&amp;
    rect.bottom &lt;= (<span class="hljs-built_in">window</span>.innerHeight || <span class="hljs-built_in">document</span>.documentElement.clientHeight) &amp;&amp;
    rect.right &lt;= (<span class="hljs-built_in">window</span>.innerWidth || <span class="hljs-built_in">document</span>.documentElement.clientWidth)
  );
}
</code></pre>
<p>Here, given a DOM element, we check the top, left, bottom and right corner's coordinates and see if it falls inside the document or the window in which the slider slides.</p>
<p>We can now use this kind of check, or something more elaborate or reactive, to decide whether to load an image into our slider container. Here's an example of how we used to load images lazily with this strategy. </p>
<pre><code class="lang-JS">
<span class="hljs-comment">/**
 * <span class="hljs-doctag">@example </span>window.addEventListener('scroll', lazyLoad);
 * */</span> 
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">lazyLoad</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> lazyImages = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'.slidey-img[data-src]'</span>);

  lazyImages.forEach(<span class="hljs-function"><span class="hljs-params">img</span> =&gt;</span> {
    <span class="hljs-keyword">if</span> (isInViewport(img)) {
      img.src = img.dataset.src;
      img.removeAttribute(<span class="hljs-string">'data-src'</span>);
    }
  });
}
</code></pre>
<p>The secret to behind the scenes lazy loading of images is just this ^. We basically just create the <code>img</code> element and/or update the <code>src</code> URL. It is a common pattern to co-locate a DOM node-specific data, like the image node's tag, under a <code>data-*</code> style attribute in that same node.
In this case, we keep <code>img</code> elements in our HTML with each of their <code>src</code> paths (e.g. <code>img/public/square/brain.png</code>) under <code>data-src</code> instead of <code>src</code>. We put that <code>data-src</code>'s value into the <code>src</code> not eagerly before the image is even needed by the UI.</p>
<p>How lazily, or early should we fetch images for the viewport? 
There are differing viewpoints on this.</p>
<p>Whether we pre-fetch or even cache pre-fetched items for long is purely dependent on the use cases we are catering to. It makes sense to eagerly load perhaps the first <code>prev</code>, <code>center</code> and <code>next</code> images. However, if we don't time our pre-fetching or delayed-fetching of images right in reactive sense, we will be exposing our audience to a lag, layout shifts and jitter-based user experience.</p>
<p>Reactivity primitives like the <code>observable</code> pattern espoused for reactive and dynamic workloads aim to solve this general class of problems too. Nevertheless, before the eponymous <a target="_blank" href="https://github.com/tc39/proposal-observable">tc-39 proposal</a>, we already have a working implementation of an <code>observer</code> API already.</p>
<p>Here's an almost canonical example, <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API">from MDN</a>, of how one would determine whether a slider-div or any other element is coming into view or is currently viewable.</p>
<pre><code class="lang-JS"><span class="hljs-keyword">const</span> options = {
  <span class="hljs-attr">root</span>: <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#scrollArea"</span>),
  <span class="hljs-attr">rootMargin</span>: <span class="hljs-string">"0px"</span>,
  <span class="hljs-attr">threshold</span>: <span class="hljs-number">1.0</span>,
};

<span class="hljs-keyword">const</span> observer = <span class="hljs-keyword">new</span> IntersectionObserver(callback, options);
</code></pre>
<blockquote>
<p>N.B. Although it is not emphasized much, there is never really a need to use <code>let</code> in production code other than for setting up test beds with a closure state like the one above for an efficient and simplified state management with adequate separation of concerns. My last production code that actually needed <code>let</code> or mutation was at least a decade ago.</p>
</blockquote>
<p>Using this <code>callback</code> function, we also achieve what is known as the <a target="_blank" href="https://martinfowler.com/bliki/HollywoodPrinciple.html">Hollywood Principle</a> in the business. Whatever it is that needs to be done by the event handler e.g. using lazy loader, pre-fetcher and/or <code>next</code>/<code>prev</code> functions when the root element of the document is visible can be done when we get a call back from the <a target="_blank" href="https://twitter.com/hollywoodobsrvr?lang=en">Hollywood Observer</a>. </p>
<blockquote>
<p>As actors, event handlers or script-writers, we don't need to be the one calling. We are supposed to be the ones receiving the call when the moment arises. We may be or need to be at different intersections. Just as we have characters in our scripts, we might ourselves need to be actors or handlers in a story or event other than ourselves. </p>
</blockquote>
<h2 id="heading-a-bit-of-meta">A Bit of Meta</h2>
<p>Note that we can still use our <code>isInViewport</code> in combination with the above intersection observer <code>callback</code> depending on our implementation logic and intuitions. In fact, it would be preferable if our final implementation builds up towards being able to reactively observe the slides while simultaneously designing the slides to be observed by a real-life alive user. </p>
<p>As programmers, and noticeably not yet professional developers, we might jump into coding sessions with a linear imperative thinking in mind or with other biases like trying to model everything as either just objects or just functions. In real-world applications, it is not about the principles or paradigms of programming or computing or any architecture over the other. Software and <code>slidey</code> things running out there in the wild, at the edge of space, oceanic, biological or commercial settings, whether all of my own in each case, or of others who wrote after having built planet scale projects, takes practical considerations and unforeseeable optimizations and indirection all the time over any philosophy.</p>
<p>As I had tried to start writing about Scala and how objects and functions can together work in mission critical systems and how we can build up towards formally verified software, I had to take an abrupt pause. COVID hit, but also I realized that not all my projects are going to be about some civilization concerning consortium projects all the time. The same in-depth, meditative, and highly-observant craftsmanship and ruthless pragmatism to solve bigger problems needs to be applied in things like sliding sliders or little buttons that make things happen. In the details lie the essence and in the essence emerge the details. </p>
<p>So, let's continue to work on smaller things, <code>slidey</code> things and just as with the calculus of constructions, we may build towards bigger <a target="_blank" href="https://plato.stanford.edu/entries/physics-structuralism/#SneeProg"><code>holons</code></a>. <code>H</code> or theory-holons are complex theory-nets tied by “essential” links in this context. To keep things simple, let's focus back on 'essentials' of a slider's physics and design.</p>
<h2 id="heading-a-short-keynote-bored-with-navigation-rodents">A Short Keynote: Bored with Navigation Rodents</h2>
<p>Do we have any agents other than the slider system itself as a whole? Users are the obvious elephants in the room and at least some of them, including me, like to operate our machines with just our keyboards. Just assume that we missed the whole memo on why mice are nice from a long forgotten but venerable <a target="_blank" href="https://en.wikipedia.org/wiki/The_Mother_of_All_Demos">Mother of All Demos</a>. This is all we ask for as ancient keyboard users who are still not finding the right click or left tap-dancing on our screens:</p>
<pre><code class="lang-JS"><span class="hljs-comment">/**
 * <span class="hljs-doctag">@example </span>document.addEventListener('keydown', handleKeyboardNavigation);
*/</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleKeyboardNavigation</span>(<span class="hljs-params">event</span>) </span>{
  <span class="hljs-keyword">switch</span> (event.key) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">'ArrowLeft'</span>:
      prev();
      <span class="hljs-keyword">break</span>;
    <span class="hljs-keyword">case</span> <span class="hljs-string">'ArrowRight'</span>:
      next();
      <span class="hljs-keyword">break</span>;
    <span class="hljs-comment">// Maybe more cases for other navigation keys if needed</span>
    <span class="hljs-keyword">default</span>:
      <span class="hljs-keyword">break</span>;
  }
}
</code></pre>
<h2 id="heading-getting-our-s-together">Getting our S#@% Together</h2>
<p>In our simplified example, the <code>sliderContext</code> had only one mutable state and one <code>const</code> reference to the slider element in our HTML. However, if we need a real-life, production-ready and/or general purpose implementation, we would not have just some values or objects or references but a whole <code>class</code> of it. Literally:</p>
<pre><code class="lang-JS">
<span class="hljs-keyword">const</span> defaultOptions = {
  <span class="hljs-attr">auto</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">infinite</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">time</span>: <span class="hljs-number">2000</span>,
  <span class="hljs-attr">forward</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// Can't we just keep `prev`ing instead of `next`ing?</span>
  <span class="hljs-attr">sibling</span>: <span class="hljs-string">'slidey-sib'</span> <span class="hljs-comment">// Can we sync with another slider on-screen?</span>
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SliderState</span> </span>{

  <span class="hljs-keyword">constructor</span>(containerSelector, options = defaultOptions) {
    <span class="hljs-built_in">this</span>.ticking = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">this</span>.container = <span class="hljs-built_in">document</span>.querySelector(
      ensureSingleDotPrefix(containerSelector)
    );
    <span class="hljs-built_in">this</span>.options = { ...defaultOptions, ...options };
    <span class="hljs-built_in">this</span>.currentIndex = <span class="hljs-number">0</span>;
    <span class="hljs-built_in">this</span>.images = <span class="hljs-built_in">Array</span>.from(<span class="hljs-built_in">this</span>.container.querySelectorAll(<span class="hljs-string">'.slidey-img'</span>));
    <span class="hljs-built_in">this</span>.dots = <span class="hljs-built_in">Array</span>.from(<span class="hljs-built_in">this</span>.container.querySelectorAll(<span class="hljs-string">'.slidey-dot'</span>));
    <span class="hljs-built_in">this</span>.prevButton = <span class="hljs-built_in">this</span>.container.querySelector(<span class="hljs-string">'.prev'</span>);
    <span class="hljs-built_in">this</span>.nextButton = <span class="hljs-built_in">this</span>.container.querySelector(<span class="hljs-string">'.next'</span>);
    <span class="hljs-built_in">this</span>.imagesLength = <span class="hljs-built_in">this</span>.images?.length ?? <span class="hljs-number">17</span>; <span class="hljs-comment">// magic number. Deal with it :sunglasses:</span>
  }
}
</code></pre>
<p>Here we have a more ambitious slider which aims to be able to provide a few more options and handles references to the current state of the slider in memory and in HTML/CSS in a single <code>class</code> that just holds the state of the slider. <code>this</code> is very hard to understand and is polymorphic and call-site dependent. So we create a class or a higher order function with closure to collect all of these objects, indexes, values, and references. In TypeScript, or an OOP supporting language like Scala or even PHP, you could protect access to these states using <code>private</code>, <code>protected</code> or <code>public</code> access modifiers which encapsulate the logic to consistently update the state variables in a guarded manner - with better separation of concerns regarding state management or value-change-tracking.</p>
<p>We can have either a companion function or <a target="_blank" href="https://docs.scala-lang.org/overviews/scala-book/companion-objects.html">object</a> which provides all the operations that are possible on the above slider with the given state of its slides. In the <code>functional</code> version, we can basically swap our earlier closure with <code>let</code>, where we already had our individual mutating index state, with a single state class <code>const</code>. </p>
<blockquote>
<p>Note that the <code>const</code> does not mean immutable values but immutable reference in JS. Subtle difference. Also, this class may effectively behave like our own <a target="_blank" href="https://vuex.vuejs.org/guide/state.html">state-store</a> after some embellishments.</p>
</blockquote>
<pre><code class="lang-JS"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SliderState</span> </span>{

  <span class="hljs-keyword">constructor</span>(containerSelector, options = defaultOptions) {
    <span class="hljs-comment">// same as above</span>
  }
}

<span class="hljs-keyword">const</span> sliderOps = <span class="hljs-function">(<span class="hljs-params">containerSelector, options = defaultOptions</span>) =&gt;</span> {

  <span class="hljs-keyword">const</span> state = <span class="hljs-keyword">new</span> SliderState(containerSelector, options);

  <span class="hljs-comment">// all the functions that need access to this state should be kept within this enclosure....</span>
}
</code></pre>
<h2 id="heading-the-state-of-slidey-things">The State of <code>Slidey</code> Things</h2>
<p>So how do we now update the pagination dots that show which of the n-images of our slider we are viewing?</p>
<pre><code class="lang-JS"><span class="hljs-keyword">const</span> updateDots = <span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> {
  state.dots.forEach(<span class="hljs-function">(<span class="hljs-params">dot, dotIndex</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (dotIndex === index) {
      dot.classList.add(<span class="hljs-string">'active'</span>);
    } <span class="hljs-keyword">else</span> {
      dot.classList.remove(<span class="hljs-string">'active'</span>);
    }
  });
}
</code></pre>
<p>In the vanilla JS world, and sometimes even in complex-but-light libraries (like <a target="_blank" href="https://preactjs.com/guide/v10/switching-to-preact/">Preact</a>), frameworks (like <a target="_blank" href="https://analogjs.org/docs/features/routing/overview#dynamic-routes">Angular/Analog</a>), meta-frameworks (like <a target="_blank" href="https://docs.astro.build/en/concepts/why-astro/">Astro</a>) and languages (like TS+<a target="_blank" href="https://gist.github.com/Rich-Harris/0f910048478c2a6505d1c32185b61934">Svelte</a>, <a target="_blank" href="https://reasonml.github.io">Reason</a>, <a target="_blank" href="https://www.scala-js.org">ScalaJS</a>), a common way to talk to the DOM is to add or remove or toggle the CSS class or other DOM attributes. This is usually done by fetching an explicit or implicit reference to the DOM element themselves or at least functions, actors, functors, applicatives, monads, transformers and/or algebraic effect systems.</p>
<p>It is also common to add or remove event listeners that react to a particular event, whenever the event (e.g. click or resize) happens. It would be a good idea to do such attachments in one place - adhering to the single responsibility principle, in some sense.</p>
<pre><code class="lang-JS"><span class="hljs-keyword">const</span> addListeners = <span class="hljs-function">() =&gt;</span> {

  state.dots.forEach(<span class="hljs-function">(<span class="hljs-params">dot, index</span>) =&gt;</span> {
    dot.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> jumpTo(index));
  });

  state.prevButton.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> prev());
  state.nextButton.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> next());
}
</code></pre>
<p>Something like centering the image is a bit non-trivial but can be achieved with a logic like this one:</p>
<pre><code class="lang-JS"><span class="hljs-comment">// utils can live outside of `sliderContext` or its `sliderOps` module</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isValidIndex</span>(<span class="hljs-params">index, length</span>) </span>{
  <span class="hljs-keyword">return</span> index &gt;= <span class="hljs-number">0</span> &amp;&amp; index &lt; length;
}

<span class="hljs-comment">// this is one of the ops inside `sliderOps`</span>
<span class="hljs-keyword">const</span> centerImage = <span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (!isValidIndex(index, state.imagesLength)) <span class="hljs-keyword">return</span>;

  <span class="hljs-keyword">const</span> currentImage = state.images[index];
  <span class="hljs-keyword">const</span> containerHalfWidth = state.container.offsetWidth / <span class="hljs-number">2</span>;
  <span class="hljs-keyword">const</span> imageHalfWidth = currentImage.offsetWidth / <span class="hljs-number">2</span>;

  <span class="hljs-keyword">let</span> totalPrevWidth = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; index; i++) {
    totalPrevWidth += state.images[i].offsetWidth;
  }

  <span class="hljs-keyword">const</span> offsetToCenter = containerHalfWidth - totalPrevWidth - imageHalfWidth;
  currentImage.parentNode.style.transform = <span class="hljs-string">`translateX(<span class="hljs-subst">${offsetToCenter}</span>px)`</span>;
  currentImage.parentNode.style.transition = <span class="hljs-string">'transform 0.9s ease-in-out'</span>;
}
</code></pre>
<blockquote>
<p>The rest of the CSS is left as an exercise to the reader. This author is not qualified enough to talk CSS and has barely put together one non-trivial CSS file recently for a feature-rich but code-golf-level minimal slider.</p>
</blockquote>
<p>When can we use <code>centerImage</code>? Sometimes it is best to keep track of the duration within which our functors need to funk or our methods/ops need to <code>op</code>. To keep things minimal and simple, this is how we achieve this:</p>
<pre><code class="lang-JS"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateSlider</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">if</span> (!state.ticking) {
    requestAnimationFrame(updateSliderPosition);
    state.ticking = <span class="hljs-literal">true</span>;
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateSliderPosition</span>(<span class="hljs-params"></span>) </span>{
  centerImage(state.currentIndex);
  state.ticking = <span class="hljs-literal">false</span>;
}
</code></pre>
<p>The <code>ticking</code> state is just a flag to keep track of one <code>tick</code> or one step or unit of movement of the cogs in our machinery. Now we can stay assured that our slider is being updated/centered in our div or viewport in the browser's own pace and cycles of animations or frame updates. </p>
<blockquote>
<p>Note that in the JS world, especially with a browser, node or bun style runtime, we think in terms of a single threaded event loop by default. Every task, micro-task, event-dispatch, animation or state update happens somewhere within this singular event-loop. Instead of jumping into the loop, we should think about submitting heavier tasks humbly to the browser's/runtime's own mechanisms and native ways of incorporating new items into the event loop. We should try not to keep the main UI thread busy or interrupted every time we want something to happen e.g. an update of a slide. We should politely/declaratively ask the browser to do it instead of imperatively imposing our linear order/steps into the loop.</p>
</blockquote>
<p>All of this does not mutate our modulo-arithmetic based slide circulation logic from before. It just adds a new step to it, which is actually just an embellished version of the last logic for the same:</p>
<pre><code class="lang-JS"><span class="hljs-keyword">const</span> next = <span class="hljs-function">() =&gt;</span> {
  state.currentIndex = (state.currentIndex + <span class="hljs-number">1</span>) % state.imagesLength;
  updateDots(state.currentIndex);
  updateSlider();
}

<span class="hljs-keyword">const</span> prev = <span class="hljs-function">() =&gt;</span> {
  state.currentIndex = (state.currentIndex - <span class="hljs-number">1</span> + state.imagesLength) % state.imagesLength;
  updateDots(state.currentIndex);
  updateSlider();
}

<span class="hljs-keyword">const</span> jumpTo = <span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (!isValidIndex(index, state.imagesLength)) <span class="hljs-keyword">return</span>;
  state.currentIndex = index;
  updateDots(state.currentIndex);
  updateSlider();
}
</code></pre>
<p>Apart from 'click' or keyboard navigation or pre-defined temporally scheduled loops, we may also get another form of user interaction: the resizing of the container or tab or window within which the slider resides.</p>
<p>Here's a simple way to do that. YMMV:</p>
<pre><code class="lang-JS"><span class="hljs-keyword">const</span> handleResize = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> maxHeight = <span class="hljs-built_in">window</span>.innerHeight * <span class="hljs-number">0.8</span>;
  <span class="hljs-keyword">const</span> maxWidth = <span class="hljs-built_in">window</span>.innerWidth * <span class="hljs-number">0.9</span>;
  state.container.style.maxHeight = <span class="hljs-string">`<span class="hljs-subst">${maxHeight}</span>px`</span>;
  state.container.style.maxWidth = <span class="hljs-string">`<span class="hljs-subst">${maxWidth}</span>px`</span>;
}
</code></pre>
<h2 id="heading-a-no-cap-recap">A No Cap Recap</h2>
<p>A function usually returns something but in the JS world we do not operate with that guarantee. A function may need to be <code>impure</code> in the sense that it manipulates some DOM node or state somewhere or even simply have a side effect like logging to the console or writing to some DB somewhere else. In such cases, it would be good to have the name of the function and its signature/documentation itself should somehow tell us what side effects are going to happen. In our case, we would prefer to have initialized the slider before returning the handlers for <code>next</code>, <code>prev</code>, <code>jumpTo</code> for use by our <code>slidey-slider</code> library's users. </p>
<p>This is essentially all that a slider does to become <code>slidey</code>:</p>
<pre><code class="lang-JS"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SliderState</span> </span>{

  <span class="hljs-keyword">constructor</span>(containerSelector, options = defaultOptions) {
    <span class="hljs-comment">// same as above</span>
  }
}

<span class="hljs-keyword">const</span> sliderOps = <span class="hljs-function">(<span class="hljs-params">containerSelector, options = defaultOptions</span>) =&gt;</span> {

  <span class="hljs-keyword">const</span> state = <span class="hljs-keyword">new</span> SliderState(containerSelector, options);

  <span class="hljs-comment">// the rest of the owl, as described above</span>
  <span class="hljs-comment">// ... </span>

  <span class="hljs-comment">// initialization routine:</span>
  addListeners();
  updateDots(state.currentIndex);
  centerImage(state.currentIndex);
  handleResize();
  <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'resize'</span>, handleResize); <span class="hljs-comment">// some listeners may be added to the window or the document in that window itself, instead of a DOM node.</span>
  initLoop(); <span class="hljs-comment">// the previously described logic for automatically looping the slidey-slides</span>

  <span class="hljs-keyword">return</span> {
    next,
    prev,
    jumpTo
  }
}
</code></pre>
<p>Where do we slide next from here?</p>
]]></content:encoded></item><item><title><![CDATA[Slide-y Thinking]]></title><description><![CDATA[This is the live documentation of how we are creating the libre slidey-things library of slider components. We will be building a basic slider and iteratively adding features and polish to it. These are some basics to cover before we dive into keyfra...]]></description><link>https://risav.dev/slide-y-thin-king</link><guid isPermaLink="true">https://risav.dev/slide-y-thin-king</guid><category><![CDATA[functions]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Vanilla JS]]></category><category><![CDATA[module-pattern]]></category><category><![CDATA[higher-order functions]]></category><category><![CDATA[Slider]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Thu, 25 Apr 2024 14:28:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1714054903023/e139066b-39ca-4af3-9bb3-374966b7e98a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is the live documentation of how we are creating the libre <code>slidey-things</code> library of slider components. We will be building a basic slider and iteratively adding features and polish to it. These are some basics to cover before we dive into keyframes, animations, pre-loading, caching, responsiveness, and browser-native optimizations.</p>
<h2 id="heading-initial-conceptions">Initial Conceptions</h2>
<ul>
<li><p>A slider may show at least one slide at once.</p>
</li>
<li><p>A slider can have a previous, central and next slide all visible at once.</p>
</li>
<li><p>Similarly, a slider can have many previous, one central and many next slides all visible at once (if they are very narrow in terms of width, assuming horizontal slides).</p>
</li>
<li><p>Sliding is defined as translating a slide from point A to point B.</p>
</li>
<li><p>Sliding and slides are not merely architectural/software constructs, they are also visual and human co-structures.</p>
</li>
</ul>
<h2 id="heading-a-minimal-version">A Minimal Version</h2>
<p>So far, we have established that a slide being shown may mean a translation to the center of view.</p>
<p>When implementing it in a browser natively without a build tool, we have to focus on HTML, CSS and JS first.</p>
<p>Here's how the HTML for such a slider may look like:</p>
<pre><code class="lang-HTML">      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"slider"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"slide-l slidey"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"img/public/square/galaxy.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Andromeda"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"slide-c slidey"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"img/public/square/brain.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Pre-frontal Cortex"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"slide-r slidey"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"img/public/square/big.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Data Architecture"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>We only have a <code>div</code> around each <code>img</code> element and a parent div classed as <code>.slider</code>. Presumably, we would need some CSS for</p>
<ul>
<li><p>the left image (<code>.slide-l</code>)</p>
</li>
<li><p>the central image (<code>.slide-c</code>)</p>
</li>
<li><p>the right image (<code>.slide-r</code>)</p>
</li>
</ul>
<p>And they all might share some common CSS config, which we could put under the <code>.slidey</code> class.</p>
<p>Various users of the sliders would want to use the slider differently and might have different tastes and design preferences.</p>
<p>We will keep our implementations open for extension and closed for modifications. Essentially, this necessitates immutable data structures and thinking of code / developmental work itself as a graphical data structure.</p>
<p>Let's grab a reference to the parent div first:</p>
<pre><code class="lang-JS">    <span class="hljs-keyword">const</span> slides = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'.slider'</span>);
</code></pre>
<p>One way of thinking about these slides would be to think as if we are meant to unroll it as a film out of a film roll.</p>
<p>In JS, this could look like this if we think of pulling out each roll via cogs attached to each of the film's edges for pulling into view:</p>
<pre><code class="lang-JS">    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showSlide</span>(<span class="hljs-params">index</span>) </span>{
        slides.forEach(<span class="hljs-function">(<span class="hljs-params">slide</span>) =&gt;</span> {
            <span class="hljs-keyword">const</span> slideWidth = slide.clientWidth;
            slide.style.transform = <span class="hljs-string">`translateX(-<span class="hljs-subst">${index * slideWidth}</span>px)`</span>;
        });
    }
</code></pre>
<p>This is for showing a slide that is n index away from the original or zeroth position.</p>
<p>We extract the <code>slideWidth</code> of a given slide by iterating through each item inside the <code>slides</code> element we queried for earlier. Every image moves to the negative X direction i.e. the left of the screen.</p>
<p>If your nth image is moved to the left by n times the <code>slideWidth</code>, it would have hopped that width n number of times towards left.</p>
<p>Why does it make sense to initially do it this way?</p>
<p>If you are n steps further away, you need to move yourself n times to get to the original or zeroth position.</p>
<p>How big are each of those steps? Let's just say you move yourself just one unit to the left.</p>
<p>If we make this 'unit' a constant for each slide, it would not really cover the required distances.</p>
<p>If we are, for example, constraining all the images to the same height and allowing each image to be of any aspect ratio / width, we need to consider each image's journey / distances individually.</p>
<p>When thinking in natural numbers, we think in terms of unit increments and decrements also aside from n number of unit increments or decrements.</p>
<p>If we are able to have an action and an inverse operation for that action, e.g. both a forward and previous button / action associated with our slider then we would have something close to what is called a 'ring' in mathematics.</p>
<p>Let's try to have a simple pair of <code>nextSlide</code> and <code>prevSlide</code> functions that act as the inverses of each other. By this, we generally mean that doing one action and then the next will lead you back to your original position or state in general.</p>
<pre><code class="lang-JS">    <span class="hljs-keyword">let</span> currentSlide = <span class="hljs-number">0</span>;

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">nextSlide</span>(<span class="hljs-params"></span>) </span>{
        currentSlide =(currentSlide + <span class="hljs-number">1</span>) % slides.length;
        showSlide(currentSlide);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">prevSlide</span>(<span class="hljs-params"></span>) </span>{
        currentSlide = (currentSlide - <span class="hljs-number">1</span> + slides.length) % slides.length;
        showSlide(currentSlide);
    }
</code></pre>
<p>Apart from using <code>let</code> in JS, it is also a bit flaky because it has two places that try to modify the same value: the value of the <code>currentSlide</code> index. Such mutation oriented code needs to be dealt with with care because of the complexities that arise in reading and writing the same value from different optical vantage points. However, since we will try to keep it as simple as possible without it being useless, we will keep the index as a closure state within our function.</p>
<p>Holding the state of the current slide in memory requires us to think of how we want to place and manage this in memory. In JS, an idiomatic way to achieve this is by using <code>closure</code> inside a functional context. In mathematics, closure is a property that usually implies that operations do not change the type of outcome. Similarly, in programming, closure is a similar property that is bounded within a lexical or functional scope, like in the following example:</p>
<pre><code class="lang-JS">    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sliderContext</span>(<span class="hljs-params">cssClass</span>) </span>{
      <span class="hljs-keyword">const</span> slides = <span class="hljs-built_in">document</span>.querySelectorAll(cssClass);
      <span class="hljs-keyword">let</span> currentSlide = <span class="hljs-number">0</span>;

      <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">showSlide</span>(<span class="hljs-params">index</span>) </span>{
        slides.forEach(<span class="hljs-function">(<span class="hljs-params">slide</span>) =&gt;</span> {
          <span class="hljs-keyword">const</span> slideWidth = slide.clientWidth;
          slide.style.transform = <span class="hljs-string">`translateX(-<span class="hljs-subst">${index * slideWidth}</span>px)`</span>;
        });
      }

      <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">nextSlide</span>(<span class="hljs-params"></span>) </span>{
        currentSlide =(currentSlide + <span class="hljs-number">1</span>) % slides.length;
        showSlide(currentSlide);
      }

      <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">prevSlide</span>(<span class="hljs-params"></span>) </span>{
        currentSlide = (currentSlide - <span class="hljs-number">1</span> + slides.length) % slides.length;
        showSlide(currentSlide);
      }

      <span class="hljs-keyword">return</span> {
        nextSlide,
        prevSlide
      };
    }
</code></pre>
<p>Here we have created a function that takes an input and returns an object with a couple of functions as an output.</p>
<p>Depending on whether you have a functional or imperative upbringing, you might call such a thing a higher order function or a 'module pattern'.</p>
<p>In the<code>index.html</code> file, with the above DOM elements for the sliders, one could add such functions as actions to dispatch when a user event like <code>click</code> happens.</p>
<p>Here's one simple way of initializing this:</p>
<pre><code class="lang-HTML">        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"js/slidey/slider.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
            <span class="hljs-keyword">const</span> slideContextA = sliderContext(<span class="hljs-string">".slidey"</span>);
        </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>And somewhere in the DOM, where you have your buttons, you could do this:</p>
<pre><code class="lang-HTML">    <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"prev"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"slideContextA.prevSlide()"</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"next"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"slideContextA.nextSlide()"</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>We obtained these two functions to use in our HTML because the module or <code>sliderContext</code> function has <code>return</code>ed that to us for use in the call site, which happens to be the <code>index.html</code> page itself in this case.</p>
<p>However, it is not always preferable to attach event listeners to the HTML itself like this, as this does not scale well with more complex use cases and large number of DOM nodes being involved.</p>
<blockquote>
<p>HTML is meant to be a language for semantic markup, and usually is best used for that itself. We can attach event listeners to HTML DOM elements within the JS itself. The trade-off in that case is that the JS needs to know at least some identifiers to find the reference or know how the HTML is structurally as a DOM tree.</p>
<p>Either way, there is not going to be a true separation of concerns between semantic, visual, and causal markers in a language meant for a structural description of a document.</p>
</blockquote>
<p>With user interface components like a slider, it is not always the case that a user interaction triggers an event. A slider could, for instance, automatically play in a loop forever or for a finite time span.</p>
<p>Here's how one could add options to <code>auto</code> the slides in a loop:</p>
<pre><code class="lang-JS">    <span class="hljs-keyword">const</span> defaultOptions = {
      <span class="hljs-attr">auto</span>: <span class="hljs-literal">false</span>,
      <span class="hljs-attr">infinite</span>: <span class="hljs-literal">false</span>,
      <span class="hljs-attr">time</span>: <span class="hljs-number">2000</span>
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sliderContext</span>(<span class="hljs-params">cssClass = <span class="hljs-string">".slidey"</span>, options = defaultOptions</span>) </span>{
      <span class="hljs-comment">// same code as before</span>
      <span class="hljs-comment">// ...</span>
      <span class="hljs-comment">// logic for looping:</span>
      <span class="hljs-keyword">if</span> (allOptions.auto) {
            <span class="hljs-keyword">const</span> intervalRef = <span class="hljs-built_in">setInterval</span>(nextSlide, allOptions.time);
            <span class="hljs-keyword">if</span> (!allOptions.infinite) {
                <span class="hljs-built_in">setTimeout</span>(<span class="hljs-built_in">clearInterval</span>(intervalRef), allOptions.time * <span class="hljs-number">2</span>);
             }
      }

      <span class="hljs-keyword">return</span> {
        nextSlide,
        prevSlide
      };

  }
</code></pre>
<p>Here we have decreed that the <code>nextSlide</code> function be called every 2000ms or any other finite duration. We have also said that if the slide is not supposed to be infinite, it should stop looping after a certain predefined amount of time.</p>
<h2 id="heading-a-minimal-requirement-analysis">A Minimal Requirement Analysis</h2>
<p>We might need to have a lot more images in a slideshow. This also does not seem like it will be smooth without the appropriate CSS for the transitions and/or animations.</p>
<p>In a more complex and publicly usable slider, what else would be required of the slider HTML components and the JS/CSS backing them? Let's explore that in the next Slide-y Thinking session.</p>
]]></content:encoded></item><item><title><![CDATA[A Stack Attack]]></title><description><![CDATA[Let's Find Ourselves Our Stack Inventory
We have now had a common work group, work space and work shop for a multi-disciplinary software/socioware team for about half a decade. For Project Ouroboros and C@ Ana, we mostly focused on contrasting and co...]]></description><link>https://risav.dev/a-stack-attack</link><guid isPermaLink="true">https://risav.dev/a-stack-attack</guid><category><![CDATA[full stack]]></category><category><![CDATA[stack]]></category><category><![CDATA[System Architecture]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Mon, 05 Apr 2021 12:11:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1617624901564/QaUelKCX7.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-lets-find-ourselves-our-stack-inventory">Let's Find Ourselves Our Stack Inventory</h2>
<p>We have now had a common work group, work space and work shop for a multi-disciplinary software/socioware team for about half a decade. For Project Ouroboros and C@ Ana, we mostly focused on contrasting and comparing the simple and dependent-type theories and finding the right use cases of type theory and categories in real-life systems running at home and in the wild. Here's a bunch of languages and their paradigms, which might also inspire your next codebase, stack or coding style - just as it did for us.</p>
<h1 id="heading-universal-stack-languages-abcs-to-xyzs">Universal Stack Languages: ABCs to XYZs</h1>
<h2 id="heading-agda">Agda</h2>
<p>Agda is a dependently typed functional programming language. It has inductive families, which are like Haskell's GADTs. However, they can be indexed by values and not just types. It also has parameterized modules, mixfix operators, Unicode characters, and an interactive Emacs interface (the type checker can assist in the development of your code). Agda is also a proof assistant, it is an interactive system for writing and checking proofs. Agda is based on intuitionistic type theory, a foundational system for constructive mathematics developed by the Swedish logician Per Martin-Löf. It was originally developed aiming to support a wide range of type theories, but the current version supports dependent types, extensible records, coercive subtyping and universe polymorphism. </p>
<h2 id="heading-bytecode-graal-vmjvmllvm">Bytecode (Graal VM/JVM/LLVM)</h2>
<p>Bytecode is a highly optimized set of instructions designed to be executed by a software interpreter. The most common example of bytecode is Java bytecode, which is interpreted by the Java Virtual Machine (JVM). GraalVM is a high-performance runtime that provides significant improvements in application performance and efficiency which is ideal for cloud environments. It is designed for applications written in JavaScript, Python, Ruby, R, JVM-based languages like Java, Scala, Kotlin, and LLVM-based languages such as C and C++. LLVM on the other hand, is a library that is used to construct, optimize and produce intermediate and/or binary machine code. LLVM can be used as a compiler framework, where you provide the "front end" (parser and lexer) and the "back end" (code that converts LLVM's representation to actual machine code).</p>
<h2 id="heading-cccarbon">C/C++/Carbon</h2>
<p>C and C++ are general-purpose programming languages which have been around for over 40 years. C++ is an extension of C, and it provides many additional features, such as classes and objects, which support the Object-Oriented Programming paradigm. This paradigm is useful for organizing large codebases and for creating reusable code. Carbon on the other hand, is a source-to-source programming language designed for writing maintainable and scalable code.</p>
<h2 id="heading-datalog">Datalog</h2>
<p>Datalog is a declarative logic programming language that is syntactically a subset of Prolog. It is often used as a query language for deductive databases. Its applications in databases include integrity constraint checking, complex event processing, and logic-based B2B integration.</p>
<h2 id="heading-eiffel">Eiffel</h2>
<p>Eiffel is an object-oriented programming language emphasizing the design and construction of high-quality and reusable software. Its model of computation is based on Hoare logic and Meyer's design by contract, where assertions form a contract between subroutines and their callers.</p>
<h2 id="heading-fortran">Fortran</h2>
<p>Fortran (formerly FORTRAN) is a general-purpose, compiled imperative programming language that is especially suited to numeric computation and scientific computing. It is one of the oldest programming languages still in use.</p>
<h2 id="heading-gleam-beam-vm">Gleam (Beam VM)</h2>
<p>Gleam is a statically typed functional programming language for building scalable concurrent systems. It compiles to Erlang and runs on the BEAM virtual machine used by Erlang and Elixir.</p>
<h2 id="heading-haxe">HaXe</h2>
<p>Haxe is a high-level cross-platform multi-paradigm programming language and compiler that can produce applications and source code, for many different computing platforms from one code-base. It is free and open-source software, distributed under the GNU General Public License (GPL) 2.0, and the standard library under the MIT License.</p>
<h2 id="heading-idris-2">Idris 2</h2>
<p>Idris 2 is a purely functional programming language with dependent types, optional lazy evaluation, and features inspired by Haskell and ML. Idris 2 is a complete reimplementation of Idris and is implemented in Idris itself.</p>
<h2 id="heading-julia">Julia</h2>
<p>Julia is a high-level, high-performance dynamic language for technical computing. It provides a sophisticated compiler, distributed parallel execution, numerical accuracy, and an extensive mathematical function library. Julia’s Base library, largely written in Julia itself, also integrates mature, best-of-breed open source C and Fortran libraries for linear algebra, random number generation, signal processing, and string processing.</p>
<h2 id="heading-skotlin-scalajs-kotlin-ui-monorepos">sKotlin (ScalaJS + Kotlin UI monorepos)</h2>
<p>Scala.js is a compiler that compiles Scala source code to equivalent Javascript code. That lets you write Scala code that you can run in a web browser. Kotlin provides a safer and more functional paradigm-based approach to using the JVM, Java, and Scala ecosystems.</p>
<h2 id="heading-lean">Lean</h2>
<p>Lean is a theorem prover and programming language designed to bridge the gap between interactive and automated theorem proving. It provides a dependent-type theory with a small number of basic axioms and inductive definitions.</p>
<h2 id="heading-miranda">Miranda</h2>
<p>Miranda is a lazy, purely functional programming language, designed for teaching and research and for specialized industrial applications. It has a strong polymorphic type system and supports higher-order functions.</p>
<h2 id="heading-nim">Nim</h2>
<p>Nim is a statically typed, compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).</p>
<h2 id="heading-ocaml">OCaml</h2>
<p>OCaml is a general-purpose programming language with an emphasis on expressiveness and safety. It is a member of the ML language family, which includes Standard ML and F#. INRIA, a French research institute, has developed and distributed it since 1996.</p>
<h2 id="heading-prolog">Prolog</h2>
<p>Prolog is a logic programming language associated with artificial intelligence and computational linguistics. It has important role in artificial intelligence. Unlike many other programming languages, Prolog is intended primarily as a declarative programming language: the program logic is expressed in terms of relations, represented as facts and rules.</p>
<h2 id="heading-q">Q</h2>
<p>Q# (pronounced as Q sharp) is a domain-specific programming language used for expressing quantum algorithms. It was initially released to the public by Microsoft as part of the Quantum Development Kit.</p>
<h2 id="heading-racket-racket-rust-backend-monorepos">Racket (Racket + Rust Backend monorepos)</h2>
<p>Racket is a general-purpose, multi-paradigm programming language based on the Scheme dialect of Lisp. It is designed to be a platform for programming language design and implementation. Racket is also used for scripting, computer science education, and research. Rust is a similarly optimized and powerful systems development language with a type-safe approach for accessing system internals and borrowing references politely.</p>
<h2 id="heading-svelte-5">Svelte 5</h2>
<p>Svelte is a modern JavaScript compiler that allows you to write easy-to-understand JavaScript code, which is then compiled to highly efficient code that runs in the browser. You can write your code using techniques that make it easy to understand, and Svelte will do the work of translating it into highly efficient code that manipulates the DOM.</p>
<h2 id="heading-typescript">Typescript</h2>
<p>TypeScript is a statically typed superset of JavaScript that compiles to plain JavaScript. It adds optional types, classes, and modules to JavaScript, and supports tools for large-scale JavaScript applications.</p>
<h2 id="heading-unison">Unison</h2>
<p>Unison is a new programming language currently under active development. It's a modern, statically-typed, purely functional language, similar to Haskell, but with the ability to describe entire distributed systems with a single program.</p>
<h2 id="heading-xslt">XSLT</h2>
<p>XSLT is a language for transforming XML documents into other formats (like transforming XML into HTML). The original document is not changed; rather, a new document is created based on the content of an existing one. XSLT uses XPath to define parts of the source document that should match one or more predefined templates. When a match is found, XSLT transform that part of the source document into the result document.</p>
<h2 id="heading-yaml">YAML</h2>
<p>YAML (a recursive acronym for "YAML Ain't Markup Language") is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or transmitted.</p>
<h2 id="heading-zig">Zig</h2>
<p>Zig is a general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software. It is an imperative, statically-typed language designed for robustness, optimality, and maintainability.</p>
]]></content:encoded></item><item><title><![CDATA[Time - III [Draft]]]></title><description><![CDATA[The Crisis in Infinite Quantum Futures
Time is also in a quantum crisis. In the previous post in this series, we have touched upon the symbolic and enumerative 'crisis' of time and the possibility that time may not exist as a feature of the symbolic ...]]></description><link>https://risav.dev/time-iii-draft</link><guid isPermaLink="true">https://risav.dev/time-iii-draft</guid><category><![CDATA[time]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Sat, 09 Jan 2021 06:55:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1610177131325/l8LBFMTIf.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-the-crisis-in-infinite-quantum-futures">The Crisis in Infinite Quantum Futures</h1>
<p>Time is also in a quantum crisis. In the <a target="_blank" href="https://risav.dev/time-ii-ck7x2qw9y029yzns11f673dtd">previous post</a> in this series, we have touched upon the symbolic and enumerative 'crisis' of time and the possibility that time may not exist as a feature of the symbolic and syntactic universe as it is but rather a feature of our modes of understanding of the symbolic universe. In this third part of the series, we will focus on two ways of understanding time and how these can be represented in mathematics or physics terms. Hopefully, this will build up the toolkit we require to easily dissect the more complex philosophical and technical arguments I would like to present in this third installation and the upcoming part of this series. </p>
<p>These two conceptions of time are also highly problematic. The classical deterministic view and the quantum probabilistic together have ugly mutual contradictions, transfinite regressions, and outdated metaphysical arguments. Furthermore, even mathematics and physics representing the various aspects of these 2 different possible universes do not claim to define time but rather just measure, calculate, or represent these conceptions of time. We will be visiting Non-Euclidean spaces and nullary spaces where time may even become a point or a line as opposed to an imaginary number or a real number in the previous post. I am getting ahead of myself here so we will start at the beginning of the philosophy of science's being and becoming in the west and then jump at least 2 millennia to find the oriental Vedic sciences again.</p>
<h2 id="heading-quantum-physics-and-quantum-field-theories">Quantum Physics and Quantum Field Theories</h2>
<blockquote>
<p>(This also assumes some sort of conservation, especially conservation of mass-energy for physical entities. This would be more fodder for this post on infinitude.)</p>
</blockquote>
<h2 id="heading-vedic-mathematics-and-astrophysics">Vedic Mathematics and Astrophysics</h2>
<blockquote>
<p>(This infinite eternal fire would be an interesting topic for this post when it becomes relevant for our discussions of infinite streams in programming and infinity's types in <a target="_blank" href="https://risav.dev/mathematics-anarchitecture-and-processes-ck5nahog004z4qps1w98ldfz0">the Mathematics' (An)architecture series</a> or for the upcoming theoretical quantum computer science topics.)</p>
</blockquote>
<h2 id="heading-the-being-and-the-becoming">The Being and The Becoming</h2>
<blockquote>
<p>I would argue that both Heraclitean ‘Panta Rhei’ and Parmenidean ‘ex nihilo nihil fit’ are arguments, sustained or otherwise, for two very different albeit interlinked contexts.</p>
</blockquote>
<h2 id="heading-categorical-dual-theories-of-time">Categorical Dual Theories of Time</h2>
<blockquote>
<p>Saying time flows is just as ridiculous as saying space flows. Our existence marches across time, not the other way round. </p>
<p>“Now he has departed this strange world a little ahead of me. [...] That signifies nothing. For us believing physicists, the distinction between past, present, and future is only a stubbornly persistent illusion.” </p>
</blockquote>
<h2 id="heading-time-on-1-2-3-or-more-planes">Time on 1, 2, 3, or more planes</h2>
<h2 id="heading-the-higher-dimensions-of-time-and-the-n-onions">The Higher Dimensions of Time and The n-Onions</h2>
]]></content:encoded></item><item><title><![CDATA[MAP IV: Mathematics as a Language - I]]></title><description><![CDATA[Is Math Invented or Discovered?
Whether mathematics is discovered or invented is an age-old question but it could also have been an innocent false dilemma all along. Could it be something in between or beyond?
An alternative approach to answering thi...]]></description><link>https://risav.dev/map-iv-mathematics-as-a-language-i</link><guid isPermaLink="true">https://risav.dev/map-iv-mathematics-as-a-language-i</guid><category><![CDATA[Math]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Thu, 29 Oct 2020 17:36:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1603975250123/C3SukD4lJ.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="is-math-invented-or-discovered">Is Math Invented or Discovered?</h1>
<p>Whether mathematics is discovered or invented is an age-old question but it could also have been an innocent false dilemma all along. Could it be something in between or beyond?</p>
<p>An alternative approach to answering this could be that mathematics is a formal language that is constructed using formal structures and operations on those structures. More precisely, mathematics is a system for deciding whether mathematical statements about a mathematical structure are true. </p>
<p>So what could make a statement mathematical? Tautologically, any statement that follows mathematical rules could be called a mathematical statement. </p>
<p>Is that last sentence in itself an exhaustive rule? That is, are there other ways to write or construct a mathematical statement? Mathematics can sometimes be about something more than a system of rules or instructions. In fact, this simple rule-based 'kind' of mathematical statements is usually a small subset of mathematical statements that map directly to the kind of statements we write in imperative programming. As an example of this think of the following multiplication as a 'mathematical statement':</p>
<pre><code> <span class="hljs-number">1234</span>
 <span class="hljs-string">x</span> <span class="hljs-number">56</span>
<span class="hljs-string">______</span>
 <span class="hljs-number">7404</span>
<span class="hljs-number">61700</span>
<span class="hljs-string">______</span>
<span class="hljs-number">69104</span>
</code></pre><p>We teach this kind of lifeless and tedious instruction set to our kids to teach them multiplication when they are starting to learn mathematics. And of course, most of them grow up to hate some parts or all of mathematics. Well there are some that do not mind these punishments. And that's how you have imperative programmers or drone-workers. However, these instruction sets in arithmetic come from the algebra of numbers, which is slightly more abstract than merely adding 1234 to itself 56 times as an arithmetician. Such algebras form mathematical structures as opposed to mere mathematical rules. </p>
<h2 id="one-of-the-rings">One of the Rings</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603974856730/Ae7HOzkKM.png" alt="ring.png" /></p>
<p>Integers form a useful structure called a ring. And a ring is a set that just so happens to have two operations,  <code>+</code> and <code>·</code> , defined on its elements and the second one, which is <code>·</code>, happens to be distributive. Furthermore, it has both right and left distributivity. With this information, we know that:</p>
<pre><code><span class="hljs-number">1234</span> <span class="hljs-string">·</span> <span class="hljs-number">56</span> 

<span class="hljs-string">=</span> <span class="hljs-number">1234</span> <span class="hljs-string">·</span> <span class="hljs-string">(50</span> <span class="hljs-string">+</span> <span class="hljs-number">6</span><span class="hljs-string">)</span> 
<span class="hljs-string">=</span> <span class="hljs-string">(50</span> <span class="hljs-string">+</span> <span class="hljs-number">6</span><span class="hljs-string">)</span> <span class="hljs-string">·</span> <span class="hljs-number">1234</span> 

<span class="hljs-string">=</span> <span class="hljs-number">1234</span> <span class="hljs-string">·</span> <span class="hljs-number">50</span> <span class="hljs-string">+</span> <span class="hljs-number">1234</span> <span class="hljs-string">·</span> <span class="hljs-number">6</span>
<span class="hljs-string">=</span> <span class="hljs-number">1234</span> <span class="hljs-string">·</span> <span class="hljs-string">(5</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span><span class="hljs-string">)</span> <span class="hljs-string">+</span> <span class="hljs-number">1234</span> <span class="hljs-string">·</span> <span class="hljs-number">6</span>

<span class="hljs-string">=</span> <span class="hljs-string">(1</span> <span class="hljs-string">·</span> <span class="hljs-number">1000</span> <span class="hljs-string">+</span> <span class="hljs-number">2</span> <span class="hljs-string">·</span> <span class="hljs-number">100</span> <span class="hljs-string">+</span> <span class="hljs-number">3</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span> <span class="hljs-string">+</span> <span class="hljs-number">4</span> <span class="hljs-string">·</span> <span class="hljs-number">1</span><span class="hljs-string">)</span> <span class="hljs-string">·</span> <span class="hljs-number">5</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span> 
<span class="hljs-string">+</span> <span class="hljs-string">(1</span> <span class="hljs-string">·</span> <span class="hljs-number">1000</span> <span class="hljs-string">+</span> <span class="hljs-number">2</span> <span class="hljs-string">·</span> <span class="hljs-number">100</span> <span class="hljs-string">+</span> <span class="hljs-number">3</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span> <span class="hljs-string">+</span> <span class="hljs-number">4</span> <span class="hljs-string">·</span> <span class="hljs-number">1</span><span class="hljs-string">)</span> <span class="hljs-string">·</span> <span class="hljs-number">6</span>

<span class="hljs-string">=</span> <span class="hljs-string">(1</span> <span class="hljs-string">·</span> <span class="hljs-number">5</span> <span class="hljs-string">·</span> <span class="hljs-number">1000</span> <span class="hljs-string">+</span> <span class="hljs-number">2</span> <span class="hljs-string">·</span> <span class="hljs-number">5</span> <span class="hljs-string">·</span> <span class="hljs-number">100</span> <span class="hljs-string">+</span> <span class="hljs-number">3</span> <span class="hljs-string">·</span> <span class="hljs-number">5</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span> <span class="hljs-string">+</span> <span class="hljs-number">4</span> <span class="hljs-string">·</span> <span class="hljs-number">5</span> <span class="hljs-string">·</span> <span class="hljs-number">1</span><span class="hljs-string">)</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span> 
<span class="hljs-string">+</span> <span class="hljs-string">(1</span> <span class="hljs-string">·</span> <span class="hljs-number">6</span> <span class="hljs-string">·</span> <span class="hljs-number">1000</span> <span class="hljs-string">+</span> <span class="hljs-number">2</span> <span class="hljs-string">·</span> <span class="hljs-number">6</span> <span class="hljs-string">·</span> <span class="hljs-number">100</span> <span class="hljs-string">+</span> <span class="hljs-number">3</span> <span class="hljs-string">·</span> <span class="hljs-number">6</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span> <span class="hljs-string">+</span> <span class="hljs-number">4</span> <span class="hljs-string">·</span> <span class="hljs-number">6</span> <span class="hljs-string">·</span> <span class="hljs-number">1</span><span class="hljs-string">)</span>   

<span class="hljs-string">=</span> <span class="hljs-number">61700</span> <span class="hljs-string">+</span> <span class="hljs-number">7404</span>
<span class="hljs-string">=</span> <span class="hljs-number">69104</span>
</code></pre><p>In the first two pairs of steps, we demonstrate that integers have left and right distributivity under the second operation <code>·</code>. In the subsequent two lines, we use associativity of this same operation i.e. </p>
<pre><code><span class="hljs-number">1234</span> <span class="hljs-string">·</span> <span class="hljs-string">(5</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span><span class="hljs-string">)</span> 
<span class="hljs-string">=</span> <span class="hljs-number">1234</span> <span class="hljs-string">·</span> <span class="hljs-number">5</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span>
<span class="hljs-string">=</span> <span class="hljs-string">(1234)</span> <span class="hljs-string">·</span> <span class="hljs-number">5</span> <span class="hljs-string">·</span> <span class="hljs-number">10</span>
</code></pre><p>Then we substitute 1234 with <code>1 · 1000 + 2 · 100 + 3 · 10 + 4 · 1</code>. Can we take it for granted that such a substitution is allowed? If we are being serious about the grammar of our language, we cannot just assume that such a substitution is allowed. </p>
<h2 id="digression-into-programming">Digression into Programming</h2>
<p>We have mentioned, albeit not clarified, in previous posts in the MAP series, that propositions and types are isomorphic. So in a sneaky typed-programmer way, we can say that this substitution is allowed as long as <code>+</code> is a pure operation and, therefore, referentially transparent. Purity simply means that for the same two operands, the operator always returns the same value and nothing else - not even any hidden consequence or side-effect. Referential transparency for an expression like <code>30 + 4</code> means that the expression is replaceable with the value of the expression e.g. <code>34</code>. How are we sure that merely 'purity' preserves this 'replaceability'? </p>
<p>Well, it is because we are guaranteed that along with the purity, we also have the rule that rings are closed under both operations i.e. <code>+</code> and <code>·</code> are always going to produce an integer result, in the case of the integer ring, or a real result, in case of the more general polynomial ring. So we know that the types of both operands and the results are the same. This is already good enough but insufficient support in our claim for allowing substitution. The more important question however is how are the semantics of <code>+</code> or <code>·</code>operation defined?</p>
<h2 id="lets-play-the-peano">Let's Play the Peano</h2>
<p>For this, we have to build numbers themselves. If we are building up numbers from scratch it is easy to construct them from the Peano axioms (rule-based) or from Church numerals (function-based). Once you have integers and define how various operations are defined on integers, it is quite easy but not trivial to construct the reals. </p>
<p>A Peano number is either a <code>0</code> or a successor of another Peano number. In Haskell, we define Peano number values like this:</p>
<pre><code><span class="hljs-keyword">data</span> Peano = Zero | Succ Peano
</code></pre><p>Obviously, <code>Zero</code> could correspond to the natural number <code>0</code>. Do we have 1 in this system yet? It could not be the first rule, which only produces <code>Zero</code> and it can only be one of these two rules but not both. This is because the pipe <code>|</code> represents a disjoint union or an 'either-or' mode of selection in this case. As for the second rule, <code>Zero</code> is the only Peano number we know so far. So the second constructor <code>Succ</code> has only <code>Zero</code> as a candidate thus far. Note that <code>Zero</code> has type <code>Peano</code>, and <code>Succ</code> has type <code>Peano -&gt; Peano</code>  i.e. it takes a Peano number and returns a Peano number. We can alternatively say that <code>Succ</code> is closed under Peano numbers. In that sense, Peano numbers are instead of 0, 1, 2, 3, 4... simply <code>Zero</code>, <code>Succ Zero</code>, <code>Succ (Succ Zero)</code>, <code>Succ (Succ (Succ Zero))</code> and so on and so on. </p>
<p>Note that we have not defined any rule that allows for any Peano number <code>x</code> such that <code>Succ x</code> evaluates to <code>Zero</code>. This is because we do not have negative numbers (yet) and thus <code>Zero</code> is not the successor of any Peano number. We can still define ring-like operations on these numbers but without the inverse operations, we only have a semi-ring or just 'rig' - a ring without the 'negative' operations. </p>
<h2 id="take-me-to-church">Take me to Church</h2>
<p>Peano numbers define numbers in terms of either a Zero or repeated application of <code>Succ</code> initially on <code>Zero</code> and then on any subsequently formed Peano numbers. In the same way, Church numerals are defined in terms of how many applications of a function is needed to 'reach' or count to that number. This is shown in this handy Wikimedia image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603979240487/A2_9Gnc-b.png" alt="churchnumbers.png" /></p>
<p>We will examine the lambda expressions on the right in further detail in the later posts in this series. The important point to note is that a number is essentially the count of how many times a function had to be applied to a base number, which is again 0 in this case too. Note that we could have started the count at 1 instead of 0 like a heathen. It is more useful to not do something reproachable of that sort.</p>
<p>Do we have a formal semantics of <code>+</code> and <code>·</code> using this foundation for numbers? Turns out we are quite close. Even the unary <code>Succ</code> above can be thought of as a <code>+</code> operation with one of the operands <code>1</code>. That is, <code>Succ Zero</code> is the same as <code>0 + 1</code> in our above school-level arithmetic that we started with. However, please note that it is not necessary to stick to a <code>Succ</code> as boring as that. We can also just as well define <code>Succ a</code> to be equivalent of <code>a + x</code> where <code>x</code> is an arbitrarily chosen but fixed Peano number. In fact, <code>Succ a</code> could just as well be <code>a - x</code> (which would generate negative numbers) or even <code>2^a</code> (which would generate powers of base 2). Both formulations of <code>Succ</code> would lead to a set of 'numbers' of the same size - even though that size or cardinality is the same countable infinity. However, we have not formally defined such addition, subtraction, or exponentiation yet so using any of the examples in this paragraph to define <code>Succ</code> would be cheating.</p>
<p>In this case, it is actually easier to not cheat and simply write the definition. Let's start with the notion of what it means to have a number <code>n</code> in our system:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603988713398/_GTAM1k0x.png" alt="fnlambda.png" /></p>
<p>As seen in the last two images, 0 is simply the result of no applications of f. 1 is the result of one application of <code>f</code>. 2 is the result of <code>f f</code>. 3 is the result of <code>f f f</code> and so on and so on. We use this to motivate the intuition behind the notion of <code>+</code>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603989267577/9V9EtoEow.png" alt="fmplusn.png" /></p>
<p>If you have <code>n</code> applications of <code>f</code> lying around and I bring you <code>m</code> applications of <code>f</code>, and if we compose those together, we have <code>m + n</code> number of applications of <code>f</code>. According to our rule, <code>m + n</code> many applications of <code>f</code> results in the number <code>m + n</code>. Note that <code>+</code> is closed under addition. So we know that the result of the expression <code>m + n</code> is the same as the value <code>m + n</code>, which is still a Church numeral. So can we now define <code>*</code>? It is actually even easier.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603989728245/Wxxtd31UX.png" alt="fmtimesn.png" /></p>
<p>If you have <code>n</code> applications of <code>f</code> lying around, just apply all of that <code>m</code> many times. That result is <code>m * n</code>. </p>
<h2 id="invented-or-discovered">Invented or Discovered?</h2>
<p>So have we invented addition and multiplication for integer/polynomial rings or Church/Peano numbers? We probably cannot claim to invent that which has pre-existed our invention of it. So did we discover them instead? This is a slightly more acceptable proposition because we did 'run into' these operations. In the same sense that Columbus 'discovered' the Americas by getting there after so many other explorers and settlers, we did 'discover' addition and multiplication from our first principles. </p>
<p>A better approach to answering this question would be that we have neither invented nor discovered any mathematics. We have simply constructed a formal* language with which addition and multiplication are defined both intensionally and extensionally. We started with setting out basic rules like what it means to have a number and then we decided what we can do with the set of that numbers. We constrained ourselves to map from a number to a number instead of mapping a number to a fruit or a planet. We thus required a closed nature of operations. We then added further constraints about what the unary <code>Succ</code> or <code>f</code> can do. This unary operation allowed us to define what it means to have something after the base number <code>Zero</code> or <code>0</code>. </p>
<p><code>f (f Zero)</code> is 2 applications of <code>f</code>. Similarly, <code>f (f (f Zero)))</code> is 3 applications of <code>f</code>. We then thought of what it would mean to compose the first number with the second one. Such a composition gives us <code>f (f (f (f (f Zero))))</code> or 5, which we defined as an addition. If we had just repeated the first number as many times as the value of the second number, we would have  <code>f (f (f (f (f (f Zero)))))</code> or 6. The reason addition and multiplication behave this way is that we defined them to be exactly like this. Thus we have just been creating structures (e.g. the ring <strong>Z</strong>) and then defining what operations are allowed (e.g. <strong>+</strong>, <strong>·</strong> ). We can do something similar when playing a logical game like the zero-player game called <strong><a target="_blank" href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Game of Life</a></strong> with the following production and termination rules for cells in an infinite grid of rectangular cells.</p>
<ol>
<li>Any live cell with two or three live neighbours survives.</li>
<li>Any dead cell with three live neighbours becomes a live cell.</li>
<li>All other live cells die in the next generation. Similarly, all other dead cells stay dead.</li>
</ol>
<p>Interestingly this allows for us to create a complete Turing machine on merely a cellular grid. This means that we have a computer with just 3 foundational rules (or first principles) and that anything that can be computed at all can be computed with just this eccentric grid (structure) and the introduction/elimination rules (operations) just like we did with the ring and its two essential and invertible operations. Is it better to say that the late John H Conway discovered the Game of Life or that he constructed it? </p>
<p>I bet it is the same answer for whether this great mathematician, or any other for that matter, discovered or constructed mathematics.</p>
]]></content:encoded></item><item><title><![CDATA[WW II and WW Covid: Diffs and Parallels]]></title><description><![CDATA[We have a global war against the allied forces of COVID-19, Climate Change, and Jingoistic Conflicts. However, this is not the first time we have found ourselves in a global war and  - if we survive this one -  it is not going to be our last. 
Here's...]]></description><link>https://risav.dev/ww-ii-and-ww-covid-diffs-and-parallels</link><guid isPermaLink="true">https://risav.dev/ww-ii-and-ww-covid-diffs-and-parallels</guid><category><![CDATA[op-ed]]></category><category><![CDATA[reflections]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Fri, 18 Sep 2020 04:10:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1600402247386/Qw9aELMS4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We have a global war against the allied forces of COVID-19, Climate Change, and Jingoistic Conflicts. However, this is not the first time we have found ourselves in a global war and <strong> - if we survive this one - </strong> it is not going to be our last. </p>
<p>Here's an account of what some of the greatest scientists agreed to do in the name of finishing a war the last time we had to face a large scale existential threat:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/7pSqk-XV2QM">https://youtu.be/7pSqk-XV2QM</a></div>
<p>Our hope is that this time around, there is a better solution than sacrificing numerous human lives to make a phallic symbol of death-threat. This was in-fact less civilized than a dog marking its territory with urination as that does not kill entire cities of innocents just to stop a fight that would kill even more. </p>
<p>Yet we like to talk of every large scale project solving a problem X and requiring our top intellectual minds as a 'Manhattan project for X'. It would be our collective failure as a civilization if the top minds we have even after more than half a century still are not any wiser than those in that original Manhattan project.</p>
]]></content:encoded></item><item><title><![CDATA[Reintroducing nep.work]]></title><description><![CDATA[nep.work in a nutshell
We are a community that develops omnichannel platforms for sales and delivery of services through work contract exchanges and pre-purchases. 

Or at least that is how I introduced nep.work on Jan 1, 2020. Note that, as develope...]]></description><link>https://risav.dev/reintroducing-nepwork</link><guid isPermaLink="true">https://risav.dev/reintroducing-nepwork</guid><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Fri, 11 Sep 2020 19:46:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1599843422308/Hj6nrcRDW.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>nep.work in a nutshell</p>
<p>We are a community that develops omnichannel platforms for sales and delivery of services through work contract exchanges and pre-purchases. </p>
</blockquote>
<p>Or at least that is how I <a target="_blank" href="https://risav.dev/introducing-nepwork-ck5294zz401bvmus1p2oskup0">introduced nep.work</a> on Jan 1, 2020. Note that, as developers of a general-purpose enterprise platform, we always mention services in a general sense and <em>never</em> in just the context of some specific type or range of services. However, by February, nep.work founders were starting to work more than "full-time" on our new-found devotion towards highly specific services providing COVID-19 combating solutions. The current beta of nep.work is thus essentially a COVID oriented rethinking of everything we wanted to do before.</p>
<p>We are still a community - a bigger, stronger one than before with many cross-disciplinary teams. </p>
<p>We still develop omnichannel platforms - but we now focus on the entire supply chain, not just on pre-purchases, sales, and delivery of the services.</p>
<h2 id="requirement-re-engineering-and-business-workflow-studies">Requirement re-engineering and business workflow studies</h2>
<p>However, we are proud to be now specializing like this to create a software ecosystem that is COVID-aware and, in many cases, redesigned with COVID concerns at the front and center. Because of this, we have also had a stronger focus on human-with-human interactions around our systems too instead of just human-with-machine interactions via our software interfaces on any given screen or projection. Thus, COVID has also forced us to rethink nep.work's core project BOSS (Business Optimization &amp; Security Services) where business workflows are the primary concern and human-machine interactions were the initial primary concern. </p>
<p>To this end, we have also worked with various Nepali organizations, big and small, to understand how classically accepted business-customer interactions can best be made digital without loss of monetary value or legal acceptance. We have also created robust integrations for project management, team management, and project-related bookkeeping for both technical and non-technical business projects. </p>
<p>We have already been able to digitally revitalize a few businesses dying of COVID recently and are hoping for a lot more such uplifting stories. Our depth and width of integrated services for Nepali businesses are unparalleled and going by our enterprise feature sets' growth rate, we will remain the ones breaking our own records and raising our own bars for quite a long time.</p>
<h2 id="payments-simplified-so-much-it-is-mathematically-impossible-to-further-simplify">Payments: Simplified so much, it is mathematically impossible to further simplify</h2>
<p>One big elephant in the room, that we wanted to actually just shoot and be done with, was the problem of money transfer as it kept coming up as a requirement in most problems our platform attempts to solve. We did not want to do anything directly related to fiat money but we also do not want anyone else to do participate in that communal madness. So, we just thought of the very last, minimal, and complete money send-receive solution we would need.</p>
<p>And we built exactly that. The least amount of unique information that uniquely identifies you in the merchant network (like that provided by the leading payment gateway in Nepal) is enough to send and receive money. The system still requires AI-assisted KYC/AML* related form fill-ups but there is no hiccup after that. You can literally just drag and drop some money into your friend's pockets. We were also thinking of strangers who just want to give back to the community by giving a little something to you in times of need. So, we came up with simplified UI with a drag-and-drop semantics or just a type-and-filter semantics for our maximally streamlined payment systems. Essentially you just need to select a friend from a dropdown and the amount is sent or you just drag and drop different amounts of money to different circles representing different users each. This is handy in a poker-tournament-like situation or when you need to send money as a group of users to another group of users for, say, a charity event. </p>
<blockquote>
<p><strong>We think it is a dangerous idea to build AML-detection ML/AI/Semantic algorithms alone. Such huge responsibilities are best handled by a group of cross-disciplinary experts.</strong></p>
</blockquote>
<h2 id="digital-contracts-and-exchanges">Digital Contracts and Exchanges</h2>
<p>Work contract exchanges and pre-purchases are still at the core of what we do. Notice that the exchange and trading of contractual documents are vastly different and more abstract than just creating or enforcing those contracts. Contracts are at the core of all assets and trades and thus also a first-class citizen of the nep.work platform.</p>
<p>Existing work contracts for each employee or business partner can get scanned and digitally signed. The nep.work-parsed contract now understands the concept of day-to-day business workflows and individual responsibilities distributed among the parties in the contract. All of these functional and behavioral descriptions of the workflow of businesses are analyzed by our system using the related contracts in the system. All the project management, team management, and customer relationship management capabilities are thus driven by the business logic derived from the contracts and agreements between all parties involved. Knowledge of the contracts also helps us in our additional plugin services for bookkeeping, customized ledgers, and product inventory management solutions. When your team members are working on any part of the contract, the system can now be aware of the current context e.g. patient searching a product category on the website or an employee looking up a return policy for a certain item. The former would receive intelligent assistance to help with the shopping - if determined to be needed. The latter could receive a complete takeover of the system in contextually looking up the specific business document needed.</p>
<p>So, you can think of us as an e-commerce platform for trading service agreements and insurances (e.g. for event organization and logistics) instead of just physical products. </p>
<p>As a semantically and contextually aware business assistant. As an operations research expert. An accounting assistant. A warehouse manager. Your trusty day-book and ledger maintenance staff at work.</p>
<p>And as a hospitality platform operational at every accessible venue instead of a particular location (e.g. hotel, stadium, government offices, hospital, website, app, etc).</p>
<hr />
<p>And then there are also these little things that we said since the very first time that we are, and still are proud to be:</p>
<h2 id="omni-channel">Omni-channel</h2>
<p>A single channel, physical or digital, is not always enough for modern e-commerce and high-frequency transactions. Neither is a basic multichannel strategy. For every nep.work trading agreement related interactions between providers and consumers, we strive to bring together all available digital and physical real estate, payment gateways, and logistical solutions. As we will have a singular (but distributed) functional core, these various interaction points for the market will always be in synchrony and harmony with each other. That said we will still have service providers with brick and mortar shops and traditional online catalog-sales style webshops and apps.</p>
<h2 id="platform">Platform</h2>
<p>Our sole product and exclusive service is the work exchange platform and its customer support program respectively. We have a foundational infrastructure for a <a target="_blank" href="https://plato.stanford.edu/entries/contractualism/">contractualist</a> service exchange, with or without money, backed by immutable, reliable and publicly verifiable structures such as blockchain and in-memory Merkle DAGs. The platform also has formal and socio-technical mechanisms to verify proof of work (PoW) for a given fulfilled contract. A verified PoW can be used for adding a new block of data to our blockchain and related persistence systems.</p>
<h2 id="sales-and-delivery">Sales and Delivery</h2>
<p>Our services can be sold as contracts, insurances, and barter agreements. When money is involved, the transactions can be made using local payment channels or our on-delivery cash service. Payments in kind or barter may be included before, during and after the delivery as per the specific Trading Agreement (TAg). We also have logistics partners and will soon announce a unified access API and SDK for our TAg management, payments, and delivery. </p>
<h2 id="work-exchange">Work Exchange</h2>
<p>Our work exchange platform goes beyond a freelancer network for posting and grabbing project offers. After a service request or offer is posted, there is either an open or closed negotiation between the provider and consumer parties. Optionally, an auction of the type chosen by the author of the post may be created to bypass negotiations and find optimum pricing options without involving <a target="_blank" href="https://www.econlib.org/archives/2010/09/the_senile_walr.html">senile Walrasians</a>.</p>
<p>Work exchange also enables us to remain self-organizing and self-preserving. We have learned from similar communities on the web and throughout history and created a public reputation-based trust system. </p>
<p>Providing such services in itself is also a part of our work exchange program.  For every project, the project's team may have various developers, artists, sponsors, volunteers, reviewers, and even the audience itself due to our democratized innovation and feedback mechanisms. Membership in certain negative income tax service provider communities can help offset your monthly income in case it dips below a predefined baseline. Similar 'buffer financing' or insurance services also exist for the projects in the nep.work community. Finally, most communities and workgroups have a meta group that is responsible for critical reviews and future roadmaps of the group.</p>
<hr />
<p>But we are also so much more.</p>
<p>And in many cases, words have not yet been invented for what we do. For instance, we have a new generation of blockchains that handle more than a million transactions per second whereas the fastest ever yet - <a target="_blank" href="https://futurepia.io/assets/img/FUTUREPIA_WhitePaper_EN.pdf">Futurepia</a> - is at ~300K TPS. </p>
<p>Unlike most of the blockchain community, we absolutely despise the decadence that cryptocurrencies have created instead of solving bigger problems. </p>
<p>Alike most of the community, we believe that the core ethos of verifiable and accountable systems backed by immutable sources of truth will bring some sense and order to our otherwise chaotic world filled with COVID, quakes, fires, floods, and <a target="_blank" href="https://www.gvi.co.uk/blog/6-critical-global-issues-what-are-the-worlds-biggest-problems-and-how-i-can-help/">a lot more</a>.</p>
]]></content:encoded></item><item><title><![CDATA[prox-e]]></title><description><![CDATA[prox-e provides simple REST APIs and dashboard to showcase CST's core functionalities &
a simple dashboard to demonstrate what the system and the APIs above can do.
docs
Github pages driven by eleventy SSG.
sync.sh
The ./sync.sh script utilizes the s...]]></description><link>https://risav.dev/prox-e</link><guid isPermaLink="true">https://risav.dev/prox-e</guid><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Wed, 26 Aug 2020 11:07:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1598440165955/Yn2K9s5CC.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><code>prox-e</code> provides simple REST APIs and dashboard to showcase CST's core functionalities &amp;
a simple dashboard to demonstrate what the system and the APIs above can do.</p>
<h2 id="heading-docs">docs</h2>
<p>Github pages driven by eleventy SSG.</p>
<h2 id="heading-syncsh">sync.sh</h2>
<p>The <code>./sync.sh</code> script utilizes the sh scripts in <code>sh</code> folder to update all the current branches with the latest from develop.</p>
<h2 id="heading-tp">tp</h2>
<p>TP stands for Transport Protocols and Transport Protobufs and Top Priority. It has three important sub-projects.</p>
<h3 id="heading-channels">channels</h3>
<p>All pub-sub and stream channels are available under this single API and SDK.</p>
<h3 id="heading-nginx">nginx</h3>
<p>All the nginx conf for all the projects will be made available here. </p>
<h3 id="heading-protocols">protocols</h3>
<p>All the OpenAPI specs and spec drafts will be made available here.</p>
<h2 id="heading-hi">hi</h2>
<p>All sub-projects in the <code>hi</code> project group are of high priority. It has three distinct sub-projects.</p>
<h3 id="heading-couch-potato">couch-potato</h3>
<p>This is currently just a collection of geojson blobs for CDN and redundant blob storage on edge networks. </p>
<h3 id="heading-cov-hub">cov-hub</h3>
<p>This is the dashboard and the central activity hub for all things related to covid for everyone as a member of any given organization or as an individual. </p>
<h3 id="heading-prox-e">prox-e</h3>
<p>This is the additional Open API server for communicating with our system and acts as a proxy to our single source of truth - core db.</p>
<h2 id="heading-md">md</h2>
<p>All sub-projects in the <code>md</code> project group are of medium priority. It has three distinct sub-projects.</p>
<h3 id="heading-indy">indy</h3>
<p>This is currently just a collection of geojson based id blobs for CDN and redundant blob storage on edge networks. </p>
<h3 id="heading-indy-pay">indy-pay</h3>
<p>This is the dashboard and the central activity hub for all things related to payments for everyone as a member of any given organization or as an individual. </p>
<h3 id="heading-indy-vot">indy-vot</h3>
<p>This is the additional Open API server for communicating with our system and acts as a proxy to our single source of consensus - core kdb.</p>
<h2 id="heading-lo">lo</h2>
<p>All sub-projects in the <code>lo</code> project group are of underground projects that serve as enablers for the other projects above. This group has three distinct sub-projects.</p>
<h3 id="heading-khetala">khetala</h3>
<p>This is currently just a collection of geojson based id-metadata blobs for CDN and redundant blob storage on edge networks. </p>
<h3 id="heading-medigai">medigai</h3>
<p>This is the dashboard and the central activity hub for all things related to medical ikigai for everyone as a member of any given organization or as an individual. </p>
<h3 id="heading-indycol">indycol</h3>
<p>This is the additional Open API server for communicating with our system and acts as a proxy to our single source of collaboration - curedit.</p>
]]></content:encoded></item><item><title><![CDATA[Behavior Specs' Specs]]></title><description><![CDATA[Introduction to Behavior Driven Development
Software development and project management is general traditionally focuses on a plan for success. This is not good enough for mission-critical and civilization scale software that also must plan for failu...]]></description><link>https://risav.dev/behavior-specs-specs</link><guid isPermaLink="true">https://risav.dev/behavior-specs-specs</guid><category><![CDATA[bdd]]></category><category><![CDATA[Behavior-Driven Development (BDD)]]></category><category><![CDATA[behavior]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Sun, 19 Jul 2020 07:02:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1595140179981/xA-YzZV6Q.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction-to-behavior-driven-development">Introduction to Behavior Driven Development</h2>
<p>Software development and project management is general traditionally focuses on a plan for success. This is not good enough for mission-critical and civilization scale software that also must plan for failure and for moving from failure or incompleteness to success or release regularly. </p>
<p>Initially, <a target="_blank" href="https://www.covidsim.team/">covidsim.team</a>’s dashboard (user interface for data visualization and inputs) and related systems like our self-hosted cloud drive (collaborative editors and storage for Word, Excel, PowerPoint, Images) and supercomputer management software (custom VPS manager) were meant only for internal usage within the research team. And since I was the only one working on the system since 2015, I did not find it necessary to formalize my software development process with a development team in mind.</p>
<p>Now that <a target="_blank" href="https://www.covidsim.team/">covidsim.team</a> is committed to testing the usage of some newly created forms by our public health team using this platform, we are going to need a proper development process for this national scale ambition. This BDD-based process is applicable for any quadrant in the <a target="_blank" href="https://hbr.org/2007/11/a-leaders-framework-for-decision-making">Cynefin model</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1595142789225/gEK9TuyUK.gif" alt="R0711C_A.gif" /></p>
<p>Picture from: <a target="_blank" href="https://hbr.org/2007/11/a-leaders-framework-for-decision-making">Harvard Business Review</a> </p>
<p>These forms and visualizations of related data that we are about to roll out are quite trivial parts of the underlying system, technically speaking. However, these are the primary way for any user to interact with our COVID-specific system components currently and they effectively form a portal to the rest of my collaborative systems. Hence it is vital to us to define the behavioral specifications for each of the newly designed forms, data files or visualizations. Without a clear consensus on the new behavior, the new feature cannot - and therefore will not - be made. These specifications will be stored on cosys.work's Nepali servers only. We will require approvals and editing from a single point of contact from the customers and me or a software lead we appoint in the future. Updates to the documents should be notified via emails.</p>
<h3 id="heading-bdd-examples-links-and-resources">BDD Examples, Links and Resources</h3>
<p>Example from: <a target="_blank" href="https://blogs.harvard.edu/markshead/what-is-behavior-driven-development/">blogs.harvard.edu/markshead</a> </p>
<p>A BDD feature file consists of one or more scenarios. These scenarios are just examples of how the application should behave from the standpoint of a user. For example, you might have a scenario that says:</p>
<blockquote>
<p>Feature: User Login </p>
<p>Given I am on the login page</p>
<p>When I attempt to login with valid credentials</p>
<p>Then I am shown the application dashboard</p>
</blockquote>
<p>And another scenario that says:</p>
<blockquote>
<p>Given I am on the login page</p>
<p>When I attempt to login with invalid credentials</p>
<p>Then I am shown a login error message</p>
</blockquote>
<p>These examples are written in English, but are still very structured. The Given portion tells the starting condition for the example, the When line tells what you actually do, and the Then tells what results are expected. </p>
<hr />
<p>More formally speaking, the given clause is there to define the pre-conditions and context for a new feature. Similarly, the when clause is there to define the user action or a software event that may need a reaction or response from the system. Finally, the then clause is there to describe the reaction, response or output expected from the system for this <a target="_blank" href="https://automationpanda.com/2017/01/30/bdd-101-writing-good-gherkin/">scenario</a>. </p>
<p>Adding feature description underneath the feature title is advisable but not usually necessary for trivial and well understood features like a normal login flow. You can also add freeform text descriptions under headers like <code>Example</code>, <code>Scenario</code>, <code>Background</code>, <code>Scenario Outline</code> and <code>Rule</code> followed by a colon (:) just like with <code>Feature:</code> above.</p>
<p>Another thing to note is that these Given-When-Then behavior specifications are not just documentational or prescriptive. They become a part of the source code of the software. The modules that have these specifications only perform what is specified in the Given-When-Then specs - nothing more, nothing less. These specifications and the software itself may change as frequently as the real-world requirements of the software change e.g. every second or week. </p>
<h3 id="heading-user-story-gt-agreement-gt-implementation">User Story -&gt; Agreement -&gt; Implementation</h3>
<p>User's needs are told as user stories. Thus a user story is a story created about how a user might use the system. These are usually sent over to the development team by the customer organization or written by the project manager. A user story usually follows the format:</p>
<blockquote>
<p>As a  [WHO]</p>
<p>I want   [WHAT]</p>
<p>So I can  [WHY]</p>
</blockquote>
<p>E.g.:</p>
<blockquote>
<p>As an admin user</p>
<p>I want to be able to create and delete non-admin user accounts</p>
<p>So I can add new employees as users to the system whenever needed</p>
</blockquote>
<p>Sometimes it is okay to just have 'As a user' as the first sentence. Since this is a common role and context, it is okay to bundle a bunch of user stories under a single 'As a user' block. After agreeing about such a story and the necessary features, a team makes a BDD spec for that user story. It will typically consist of a few Given-When-Then described features with logical connectives like 'and', 'or', 'not', 'with', 'but', 'once' or 'never'. Note that popular BDD tools like Gherkin only permit 'and', '*' and 'but' aside from 'given', 'when' and 'then'.</p>
<p>For example, our first user story could be about how someone from a municipality office logs in to her/his municipality’s system and what pages and data the user could expect to see and use. This story may have different scenarios e.g. whether or not the login credentials were valid, like in the earlier examples from Mark Shead.</p>
<p>Another user story we might need soon after launch is the story that imagines and describes how a user from EDCD/NPHL/NHRC/CCMC/MOHP could upload to the system. In this case, we may assert in the given clause that the user is already logged in. We could also create a <a target="_blank" href="https://www.hindsightsoftware.com/persona-cards-product-owner">user persona</a> e.g. Biplav is a non-technical user at EDCD who is responsible for EDCD's side of data updates to the system every day. </p>
<p>So, this story could initially look like this:</p>
<blockquote>
<p>Feature: CSV File Upload</p>
<p><strong>Given</strong> Biplav is logged in to the dashboard</p>
<p><strong>When</strong> Biplav clicks the CSV file uploader in the left sidebar</p>
<p><strong>Then</strong> Biplay should be able to select, preview, review, upload <strong>or</strong> cancel the upload </p>
</blockquote>
<p>These kinds of user stories may need further breakdown. This breakdown itself will also consist of more GWT sets. For example, this GWT set further explains what the system should do:</p>
<blockquote>
<p>Feature: CSV File Upload</p>
<p>Scenario Outline: Invalid CSV File Review</p>
<p><strong>Given</strong> Biplav has selected a CSV file to upload to the database using the file uploader <strong>and</strong> Biplav has not yet confirmed the upload</p>
<p><strong>When</strong> The system informs him of any mistakes like "" mistake</p>
<p><strong>Then</strong> Biplav should be able to edit the CSV headers <strong>and/or</strong> data before he cancels <strong>or</strong> confirms upload of the data.</p>
<p>Examples: Mistakes</p>
<p>| csv-invalid | </p>
<p>| invalid number of rows |</p>
<p>| a non-standard font or language is used |</p>
<p>| the file is encrypted or corrupted |</p>
</blockquote>
<p>We can have many examples of inputs, outputs or options in general in the example section to clarify things. </p>
<p>A <strong>Given</strong> sentence can be directly followed by a <strong>Then</strong> sentence too. It is usually okay to put such statements as a rule e.g.:</p>
<blockquote>
<p>Rule: Selecting an invalid CSV file should not disallow correction and eventual upload of the CSV file.</p>
<hr />
<p>Note that we use this same structure every time because this has to be understood by software too and not just the humans.</p>
</blockquote>
<p>Gherkin is a popular software interpretable GWT syntax. It is used to run behavior driven tests in the Cucumber testing framework. You can find the reference for the Gherkin syntax <a target="_blank" href="https://cucumber.io/docs/gherkin/reference/">here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1595142730242/xAIf2p5vm.png" alt="bdd-practices-diagram.png" /></p>
<p>Picture from:  <a target="_blank" href="https://cucumber.io/docs/bdd/">cucumber.io</a> </p>
<hr />
<p>How the system <strong>could</strong> behave is a crucial part of the development process. This is the <strong>discovery phase</strong> and is typically gathered via interactive sessions and workshops with some of the potential users of the system. The discovery phase allows for surfacing and formalizing organizational rules and a shared understanding. </p>
<p>An even more important part of development is the finer details of how the system <strong>should</strong> behave. This is done in the <strong>formulation phase</strong>. We create specifications, mocks, wireframes and break user stories into feasible epics or tasks in this phase.</p>
<p><strong>Automation</strong> phase is about how the system actually behaves. Validation and demonstration of each automated process may lead to further discoveries and formulations.</p>
]]></content:encoded></item><item><title><![CDATA[The Couch & The Potato]]></title><description><![CDATA[The Couch Potato

The Couch
When you are in the couch, you just need to be. The couch provides it all.
The Potato
The Potato always does something. The Potato does it all.]]></description><link>https://risav.dev/the-couch-and-the-potato</link><guid isPermaLink="true">https://risav.dev/the-couch-and-the-potato</guid><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Sat, 18 Jul 2020 03:14:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1595042075931/4hZDfDuPT.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-the-couch-potato">The Couch Potato</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1595041992480/laZDyCbYg.jpeg" alt="109705019_277296610386239_6287129039043097918_n.jpg" /></p>
<h2 id="heading-the-couch">The Couch</h2>
<p>When you are in the couch, you just need to be. The couch provides it all.</p>
<h2 id="heading-the-potato">The Potato</h2>
<p>The Potato always does something. The Potato does it all.</p>
]]></content:encoded></item><item><title><![CDATA[Socioware Specs: High Hopes]]></title><description><![CDATA[a. Bottoms Up
The following article is a follow up article about covidsim.team's call for collaboration. Contributing to the software systems will be easier once we have a common specification and description of the systems in place. 

Encumbered for...]]></description><link>https://risav.dev/socioware-specs-high-hopes</link><guid isPermaLink="true">https://risav.dev/socioware-specs-high-hopes</guid><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Sat, 18 Jul 2020 01:24:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1595035453358/ktj9k--Ws.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-a-bottoms-up">a. Bottoms Up</h2>
<p>The following article is a follow up article about <a target="_blank" href="https://www.covidsim.team">covidsim.team</a>'s <a target="_blank" href="https://risav.dev/covid-19-simulation-for-nepal-a-call-for-collaboration-ck85cqi1l0089zbs1bhjyawxd">call for collaboration</a>. Contributing to the software systems will be easier once we have a common specification and description of the systems in place. </p>
<blockquote>
<p>Encumbered forever by desire and ambition</p>
<p>There's a hunger still unsatisfied</p>
<p>Our weary eyes still stray to the horizon</p>
<p>Though down this road we've been so many times</p>
<ul>
<li>Pink Floyd, <em>High Hopes</em></li>
</ul>
</blockquote>
<h3 id="heading-1-ux-and-services">1. UX and Services</h3>
<p>User interfaces and interaction patterns of this system are built orthogonally and in bulk. Because of this we are able to create new user interface elements using component factories and resolvers. We are able to do this on the fly instead of handcrafting them each time there is a new emergent use case. Therefore, most of this document is dedicated to the rest of the 6 layers in our octal system in which two UI/UX systems cover user inputs and visualizations. </p>
<p>The user experience is designed with a decentralized burden of responsibility. Every interface and API response type describes its own visualizations and pipelines. Hence simply streaming them through a UI component resolver is enough to get a new feature displayed to the user for use. This only defines our time to user. Our time to user interaction is however still dependent on how fast we fetch all the interaction endpoint services.</p>
<h3 id="heading-2-couchdb-and-prox-e">2. CouchDB and prox-e</h3>
<p>The client is a light weight UI and windowing system for ambient computing. It also powers VR/AR interactions apart from Smart TV and Smart phone interfaces. The NoSQL database provides all the necessary data to the local system. All data processing APIs for CouchDB data is able under Potato API provided by a <code>prox-e</code> ubiquitous server instance. </p>
<p> 2,50,00,000 (25 KK) pouch instances, 753 couch instances and 7 potato instances will be needed for an optimal run in our system launch for Nepal. We are possibly starting with Lalitpur Municipality in the central Kathmandu valley and in Karnali remote province. </p>
<h3 id="heading-3-redis-and-pub-sub">3. Redis and pub-sub</h3>
<p>More intensive applications aside from the dashboard will be needed for other spreading disasters and calamities. For example, for flood-detection we need to be monitoring weather patterns and running the stream against our climate knowledge base pipelines. Similarly, an earthquake response system will guide us out of any building and towards safety only if we provide our software system with the authentic and real time 3D API of our surrounding reality. Since every concept in the system has its own data streams and behavior sets for any given context, it is easier to just fan-out using pub-sub and close-in using topics and filters. </p>
<p>Each topic has associated filtering processes related to identity, auth, context and content. Each component has multiple topics of linked data. A higher order component handles many such components including lazy loading components as needed. Our dashboard is capable of providing a windowing system overlaid on a map or some other 3D surface because every user experience of the system is channeled through a collection of components which in turn are a collection of pub-sub topics.</p>
<h3 id="heading-4-state-and-data">4. State and Data</h3>
<p>Our applications on their own and in integration have different system states. This data needs to be available and persisted. Without the ability to freeze and resume, we cannot really address all possible failure scenarios. Our systems use state and data management to travel back and forth in time and test itself in parallel even when it is being used. </p>
<p>Because fuzzers and testers of this system continually emulate all possible states and data interactions - using actions, effects and reducers, we are able to have high confidence in the system. And in the new parts of the system that the overall system creates for itself based on the results of those tests and fuzzers. </p>
<h2 id="heading-b-reactive-components">b. Reactive Components</h2>
<h3 id="heading-1-abstract-components">1. Abstract Components</h3>
<h3 id="heading-2-auth-amp-context-ui-filters">2. Auth &amp; Context UI filters</h3>
<h3 id="heading-3-ui-factories-amp-resolvers">3. UI Factories &amp; Resolvers</h3>
<h3 id="heading-4-labels-amp-processes">4. Labels &amp; Processes</h3>
<h2 id="heading-c-ngrx-breeze">c. NgRx Breeze</h2>
<h3 id="heading-1-rx-rsmq">1. rx rsmq</h3>
<h3 id="heading-2-hibernate-amp-spark">2. Hibernate &amp; Spark</h3>
<h3 id="heading-3-git-like-command-queues">3. Git-like Command Queues</h3>
<h3 id="heading-4-being-amp-performance">4. Being &amp; Performance</h3>
<h2 id="heading-d-top-down">d. Top Down</h2>
<h3 id="heading-1-concept">1. Concept</h3>
<h3 id="heading-2-relation">2. Relation</h3>
<h3 id="heading-3-knowledge">3. Knowledge</h3>
<h3 id="heading-4-representation">4. Representation</h3>
]]></content:encoded></item><item><title><![CDATA[Mastery isn't the problem, Slavery is]]></title><description><![CDATA[Why Git repository providers needn't rename master
Mastery of a certain concept or skill is probably not our problem. Mastery over other people's human rights is. However, we delegate such mastery to structures of power all the time. This is because ...]]></description><link>https://risav.dev/mastery-isnt-the-problem-slavery-is</link><guid isPermaLink="true">https://risav.dev/mastery-isnt-the-problem-slavery-is</guid><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Thu, 16 Jul 2020 09:00:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1594890000475/j72aU0pHh.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="why-git-repository-providers-needn-t-rename-master-">Why Git repository providers needn&#39;t rename <code>master</code></h1>
<p>Mastery of a certain concept or skill is probably not our problem. Mastery over other people&#39;s human rights is. However, we delegate such mastery to structures of power all the time. This is because of an outdated social contract with unregulated late stage capitalism. </p>
<p>To actually do something beyond just a symbolic rename, GitHub, for instance, just needs to actually remove different forms of mastery because of organizational and managerial constraints. </p>
<p>For there to be any freedom to work but work unlike a slave, we need freedom to not work and still exist. This basic idea is connected not just to universal income but deeper constructs as well, e.g. negative income taxes and basic social equities. </p>
<h2 id="we-need-to-be-trained-before-work">We need to be trained before work</h2>
<p>Learning to work needs to happen before work. This is especially so as to not let it mix up the organizational roles like &#39;interns&#39; or another vague / undescriptive title.</p>
<p>With qualification, we need to have matching contractual offers. This is handled on an abstract and extensible + self-hosted way within <a target='_blank' rel='noopener noreferrer'  href="https://risav.dev/introducing-nepwork-ck5294zz401bvmus1p2oskup0">nep.work</a> core. </p>
<h2 id="removing-master-">Removing <code>master</code></h2>
<p>Renaming master should be a local choice of the repository owners, not a globally imposed constraint from structures like Microsoft&#39;s GitHub. </p>
<p>This can be done with an easy script that could just be added to any CI/CD pipeline. </p>
]]></content:encoded></item><item><title><![CDATA[Suggestions from Papa]]></title><description><![CDATA[Some great tips from John Papa and why you should (not) follow them:
RxJS Subscriptions

The first one is from a 2019 ng-conf talk where he suggests that one should unsubscribe from all our subscriptions reliably once we are done with them, typically...]]></description><link>https://risav.dev/suggestions-from-papa</link><guid isPermaLink="true">https://risav.dev/suggestions-from-papa</guid><category><![CDATA[John Papa]]></category><category><![CDATA[NgRx]]></category><category><![CDATA[State Management ]]></category><category><![CDATA[subscriptions]]></category><category><![CDATA[RxJS]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Fri, 10 Jul 2020 22:33:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1594442859835/5zNWancxS.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Some great tips from John Papa and why you should (not) follow them:</p>
<h2 id="heading-rxjs-subscriptions">RxJS Subscriptions</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1594414506336/G85_Apzih.png" alt="screenshot.png" /></p>
<p>The first one is from a 2019 ng-conf talk where he suggests that one should unsubscribe from all our subscriptions reliably once we are done with them, typically in <code>ngOnDestroy</code>. </p>
<p>It would be unfortunate to need to install his proposed / friend's <code>subsink</code> library just so you can add all subscriptions to it and then unsubscribe from all of the using a single unsubscribe to the sink. RxJS <code>Subscription</code> allows you to do this natively. Here's a code snippet from the <a target="_blank" href="https://rxjs-dev.firebaseapp.com/guide/subscription">Firebase RxJS guide</a>:</p>
<pre><code class="lang-JavaScript"><span class="hljs-keyword">import</span> { interval } <span class="hljs-keyword">from</span> <span class="hljs-string">'rxjs'</span>;

<span class="hljs-keyword">const</span> observable1 = interval(<span class="hljs-number">400</span>);
<span class="hljs-keyword">const</span> observable2 = interval(<span class="hljs-number">300</span>);

<span class="hljs-keyword">const</span> subscription = observable1.subscribe(<span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'first: '</span> + x));
<span class="hljs-keyword">const</span> childSubscription = observable2.subscribe(<span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'second: '</span> + x));

subscription.add(childSubscription);

<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Unsubscribes BOTH subscription and childSubscription</span>
  subscription.unsubscribe();
}, <span class="hljs-number">1000</span>);
</code></pre>
<p>You can also abstract away this repeated <code>unsubscribe</code> in <code>ngOnDestroy</code> business as mentioned by Wojciech Trawiński <a target="_blank" href="https://medium.com/javascript-everyday/yet-another-way-to-handle-rxjs-subscriptions-1f15554ce3b5">here</a>:</p>
<pre><code class="lang-TypeScript">
<span class="hljs-keyword">import</span> { OnDestroy } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/core"</span>;
<span class="hljs-keyword">import</span> { Subscription, Observable, PartialObserver } <span class="hljs-keyword">from</span> <span class="hljs-string">"rxjs"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> SelfUnsubable <span class="hljs-keyword">implements</span> OnDestroy {
  <span class="hljs-keyword">private</span> subSink = <span class="hljs-keyword">new</span> Subscription();

  ngOnDestroy() {
    <span class="hljs-built_in">this</span>.subSink.unsubscribe();
  }

  <span class="hljs-keyword">protected</span> subscribe&lt;T&gt;(
    observable: Observable&lt;T&gt;,
    observerOrNext?: PartialObserver&lt;T&gt; | (<span class="hljs-function">(<span class="hljs-params">value: T</span>) =&gt;</span> <span class="hljs-built_in">void</span>),
    error?: <span class="hljs-function">(<span class="hljs-params">error: <span class="hljs-built_in">any</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>,
    complete?: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>
  ): Subscription {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.subSink.add(
      observable.subscribe(observerOrNext <span class="hljs-keyword">as</span> <span class="hljs-built_in">any</span>, error, complete)
    );
  }

  <span class="hljs-keyword">protected</span> unsubscribe(innerSub: Subscription) {
    <span class="hljs-built_in">this</span>.subSink.remove(innerSub);
    innerSub.unsubscribe();
  }
}
</code></pre>
<p>Now you have a less error-prone way of managing subscriptions without any external library and just good ol' OOP.</p>
<pre><code class="lang-TypeScript">
<span class="hljs-keyword">import</span> { Component, Input, OnInit } <span class="hljs-keyword">from</span> <span class="hljs-string">"@angular/core"</span>;
<span class="hljs-keyword">import</span> { interval, Subscription } <span class="hljs-keyword">from</span> <span class="hljs-string">"rxjs"</span>;

<span class="hljs-keyword">import</span> { SelfUnsubable } <span class="hljs-keyword">from</span> <span class="hljs-string">"./selfUnsubable"</span>;

<span class="hljs-meta">@Component</span>({
  selector: <span class="hljs-string">"counter"</span>,
  template: <span class="hljs-string">`
    &lt;div&gt;Count {{ count }}&lt;/div&gt;
  `</span>
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CounterComponent <span class="hljs-keyword">extends</span> SelfUnsubable {
  count = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">private</span> manualSub: Subscription;

  ngOnInit() {
    <span class="hljs-comment">// unsubscribed manually </span>
    <span class="hljs-built_in">this</span>.manualSub = <span class="hljs-built_in">this</span>.subscribe(interval(<span class="hljs-number">500</span>), <span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> {
      <span class="hljs-built_in">this</span>.count++;
      <span class="hljs-built_in">console</span>.log(value);
    });

    <span class="hljs-comment">// unsubscribed when component is destroyed</span>
    <span class="hljs-built_in">this</span>.subscribe(interval(<span class="hljs-number">1000</span>), <span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> {
      <span class="hljs-built_in">this</span>.count++;
      <span class="hljs-built_in">console</span>.log(value);
    });

   <span class="hljs-built_in">setTimeout</span>(<span class="hljs-built_in">this</span>.unSubManually, <span class="hljs-number">600</span>);
  }

  unSubManually() {
    <span class="hljs-built_in">this</span>.unsubscribe(<span class="hljs-built_in">this</span>.manualSub);
  }
}
</code></pre>
<p>But wait, there's more. We can still do better.</p>
<blockquote>
<p>Try your best not to subscribe in the first place!</p>
</blockquote>
<p>Why is it that you are introducing imperative programming by subscribing to your reactive streams in the first place? The <code>async</code> pipe is there to handle exactly this problem. You can even use <code>OnPush</code> change detection strategy if you are just putting the stream directly into your components. This is much more effective than relying on zone.js based default change detection strategy. Here are two helpful talks on this topic:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/-4cwkHNguXE">https://youtu.be/-4cwkHNguXE</a></div>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/Z76QlSpYcck">https://youtu.be/Z76QlSpYcck</a></div>
<h2 id="heading-ngrx-data">NgRx Data</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1594420522006/mhGVX3hBt.png" alt="screenshot (2).png" /></p>
<p>As NgRx developers are cautious to point out, you do not usually need NgRx. By this they usually mean that your app probably does not have use cases to justify the hundreds of lines of code bloat that NgRx requires for each of your state models.</p>
<p>A neat boilerplate code reduction can be achieved by <code>@ngrx/data</code>. If you are already using NgRX, it goes without saying that you should at least consider using this library to significantly reduce your store related code's size. However, if you are not already using NgRX, should you use it now that <code>@ngrx/data</code> is there to simplify things for you?</p>
<p>I personally favor using a full-fledged client-side immutable database instead of some immutable'store'. This has become easier than ever since PouchDB showed up and brought sanity to in-browser database-like solutions. Do you really need all the indirections, actions, effects, reducers, dispatchers, and selectors for each of your models? Most, if not all, of the time, you just need a basic reading of pure functional programming practices and an actual database with immutability or append-only behavior. Also note that actions, effects, reducers, dispatchers, and selectors can be thought of as general coding patterns instead of NgRX exclusive ideas. </p>
<p>So, is NgRx completely avoidable for even the most complex state management use cases? Your mileage may vary with the Couch-Pouch-like solution for state management. It even allows for syncing the current state to a remote server, possibly running async analytics, e.g., on user behavior, with very few additional lines of code. There is a lot more that you usually need to do with your application state than just put it in a 'store' manager. Keep it all simple by just using a database and immutable data structures.</p>
<p>You can use PouchDB even with databases with topic-wise event hooks like the Realtime and Firestore databases from Firebase or with web APIs with webhooks or push / pub-sub semantics. In any case, complex UI states can be easily stored and managed in client side in-memory stores or browser-based databases with or without state management solutions, even with boilerplate reducing solutions like NgRx Data, NgXS or Akita. </p>
<p>One particularly remarkable use case of NgRx is the possibility to create truly reactive updates to Angular without using zone.js. Here is an excellent talk from Mike Ryan regarding this exciting possibility.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/rz-rcaGXhGk">https://youtu.be/rz-rcaGXhGk</a></div>
<h2 id="heading-more">More</h2>
<p>Best practices and patterns for complicated software from big companies are not always the best for simpler projects. I will add more such (anti)-patterns here.</p>
]]></content:encoded></item><item><title><![CDATA[Anarchitecture & Skunkworks]]></title><description><![CDATA[This article describes the road map for research & development in the area of enterprise collaboration architecture, unified research and sharing of intellectual and digital assets. We then describe how this enables nep.work to operate a Skunkworks-l...]]></description><link>https://risav.dev/anarchitecture-and-skunkworks</link><guid isPermaLink="true">https://risav.dev/anarchitecture-and-skunkworks</guid><category><![CDATA[skunkworks]]></category><category><![CDATA[collaborative systems]]></category><category><![CDATA[collaboration platforms]]></category><category><![CDATA[Collaboration strategies]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Fri, 03 Jul 2020 15:30:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1594443197644/LCcaXUSKV.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong>This article describes the road map for research &amp; development in the area of enterprise collaboration architecture, unified research and sharing of intellectual and digital assets. We then describe how this enables nep.work to operate a Skunkworks-like cross-organizational framework for radical innovations not otherwise possible within the confines of organizational silos. </strong></p>
</blockquote>
<h2 id="heading-introduction">Introduction</h2>
<p>Multiple pioneering players in industry are working on overlapping interests. While competition between individual companies is the key to driving innovation in a free market, it is not particularly optimal for the market as a whole because it involves significant duplication of similar efforts and investments. Redundancies within the systems of production especially in a resource constrained nation like ours can be reduced by our proposed model of forming large collaborations and fostering competitions between collaborating groups as opposed to that between individual companies. This way companies can also level the playing field when it comes to the more concerning competition with large foreign business entities.</p>
<p>Skunkworks is a corporate practice that originated 77 years ago as a radical approach for quick delivery of better products than the competition. In Lockheed Martin's eponymous case, the end product was a fighter jet expected to fly 200 miles per hour faster than the best in competition - high-speed German fighter jets, which were literal threats - but to be completed in just 180 days. This originally utilized an isolation-based approach to enable radically innovative work. In its current form, it still bypasses bureaucracy via selective isolation but it judiciously crosses departments and even organizations especially when given the right tools and protocols. Ideally companies should be continuously innovating and not needing a dedicated Skunkworks team. However, we need to initially resolve the problem that low capital companies can only do incremental innovations despite much needed large-scale breakthroughs for the overall market, owing to a less literal but devastating threat from multinationals and powerful foreign players.</p>
<p>Mass adoption of some of these enterprise technologies, both prospective or already developed, imply a tectonic shift in industry. Although these are not moonshot projects, these are still significantly challenging for most companies to carry out on their own. To this end, we have selectively consolidated parallel research and development efforts in multiple partnering companies to create a unified front that encompasses key areas of high interest to the business community. These projects will be open sourced under the stewardship of NAAMII's I &amp; I committee, which will also include various pioneering business leaders, and will have representations from the overall business community via a community process with an open RFC driven decision making. The main focus is on collaboratively solving the industry's present problems with the most significant returns on investment or impact on business workflow optimization.</p>
<h3 id="heading-concepts-ontologies-amp-network-variants">Concepts, Ontologies &amp; Network Variants</h3>
<p>Businesses and business processes have an inherent redundancy and re-actions involved. To do more than what we are doing now, we need to automate what we are doing now. To automate processes, we should start with annotating processes. We need to identify processes and connect them as needed. Each of the nodes in such a system is essentially model-able as a node in a social-political hyper-graph. Some of the nodes may be an individual. Since these nodes are admitted in a type agnostic way, any kind of node may exist. Some nodes may just be friendship's graph friends or some may be just representation of business workflow for writing, editing, approval, signing, sending, receiving, acknowledging and responding documents. These documents can form companies, organizations, projects, business deals and execution project's team playground.</p>
<h3 id="heading-what-to-not-do">What to Not Do</h3>
<p>Since we are dealing with broad topics and scopes, we need to focus the efforts and scopes especially when getting started. In doing so, we also need to see what needs to be done first and what else can be done along with it. We propose starting simply with the beginning - entities and identities in a CoSys knowledge base (KB) or database (DB).</p>
<h3 id="heading-where-to-begin">Where to Begin</h3>
<p>We begin and end this document with the matrix. This was written around 2012-13 and has been the effective outline till the next decade.</p>
<h4 id="heading-identity">Identity</h4>
<p>An identity is a key with which the credential server returns the entity itself.</p>
<h4 id="heading-entity">Entity</h4>
<p>  Any construct or structure in our DB or KB that has an identity is called an entity.</p>
<h3 id="heading-id-ip">ID-IP</h3>
<p>  Identity that is e2e and p2p connected to identity's IP (intellectual property).</p>
<h4 id="heading-codes">Codes</h4>
<p>Code can be 1 dimensional in case of numbers or non-nested arrays.</p>
<h4 id="heading-algebras">Algebras</h4>
<p>Codes have tuples of inputs which form algebraic structures and algebras.</p>
<h4 id="heading-sciences">Sciences</h4>
<p>Code libraries of academic contexts and custom constants and constraints.</p>
<h4 id="heading-environment">Environment</h4>
<p>Code integrations form end to end systems in a given Environment.</p>
<h3 id="heading-pi-id">PI-ID</h3>
<p>Property IDs that are e2e and p2p connected to identity's IP and contexts.</p>
<h4 id="heading-q-queries">Q Queries</h4>
<p>Code query params can are always part of a unit dimensional array.</p>
<h4 id="heading-i-space">I Space</h4>
<p>Codes' IDs are in a tuple space with custom algebraic structures and algebras.</p>
<h4 id="heading-j-resource">J Resource</h4>
<p>Codes live within distinct resources of academic contexts and constraints.</p>
<h4 id="heading-k-environment">K Environment</h4>
<p>Code integrations form end to end systems in a given environment.</p>
<p>Are there things that have no identities? What can we do about those that do? What should we not do? Simply put we do not do anything other than GET, PUT, POST and OPTIONS.</p>
]]></content:encoded></item><item><title><![CDATA[Thoughts on Covidiocracy]]></title><description><![CDATA[Cover Illustration is from  XKCD#2278 

I would like to note a few concerning semantic and naming gymnastics pulled off by the media and WHO during this crisis. This list might become a lot longer in the future once I find the time to return back to ...]]></description><link>https://risav.dev/thoughts-on-covidiocracy</link><guid isPermaLink="true">https://risav.dev/thoughts-on-covidiocracy</guid><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Mon, 13 Apr 2020 21:37:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1586813668773/mo9D4r8vq.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Cover Illustration is from  <a target='_blank' rel='noopener noreferrer'  href="https://xkcd.com/2278/">XKCD#2278</a> </p>
</blockquote>
<p>I would like to note a few concerning semantic and naming gymnastics pulled off by the media and WHO during this crisis. This list might become a lot longer in the future once I find the time to return back to it:</p>
<ul>
<li><p><strong>Social Distancing</strong>: We actually need to grow closer together than ever. What we need is &#39;physical distancing&#39; from both the people and the things they touch. Very different things and very different kind of messaging.</p>
</li>
<li><p><strong>COVID-19 virus</strong>: This name for the virus instead of the actual technical name <code>SARS-CoV-2</code> (the virus that causes the COVID-19 disease) makes it sound as if this is a 2019+ problem. It completely hides the fact that this family of virus was known since 1930s and that human-infecting SARS related coronavirus have been known and are being warned about since the early 2000s. </p>
</li>
</ul>
<blockquote>
<p><strong>Let&#39;s not have any doubt on whether this is indeed SARS 2.0. It is. And it is here because we have been ignoring all the expert warnings about the next re-emergence of SARS and even defunding antivirus researches for SARS related coronavirus.</strong></p>
</blockquote>
<ul>
<li><p><strong>Kung Flu/Chinese Virus</strong>: Wuhan Virus would have been consistent with past nomenclature but giving racist nicknames or attaching nationality as opposed to a region of origin wouldn&#39;t be fair.</p>
</li>
<li><p><strong>Lockdown</strong>: A lockdown is a harsher word for a strict quarantine and conjures imprisonment related imagery due to semantic adjacency with &#39;lock up&#39;. It&#39;s still more acceptable than &#39;curfew&#39; though. In some places, stronger words might actually be necessary. However it brings resistance from the people in countries who are skeptical of their government&#39;s power grabs.</p>
</li>
<li><p><strong>Infection/Death count</strong>: Although it is implicit in the name, these numbers only reflect the known infections or known deaths. Either &#39;reported&#39; or &#39;confirmed&#39; as qualifiers might be needed more often than not in public communications. Even the richest countries have not had enough tests done per capita to know the correct numbers. </p>
</li>
</ul>
<p>To make things worse, countries are scrambling to save face and keep their actual numbers hidden. NYC recently had a very unusually high surge in &#39;heart attack&#39; related deaths. China somehow has ridiculously low number of new cases per day.</p>
<p>This part of the rant was inspired by Bill Maher making some sense with his unpopular opinion in his <a target='_blank' rel='noopener noreferrer'  href="https://youtu.be/dEfDwc2G2_8">New Rule monologue</a> on the issue of naming the virus as per the academic tradition, among other things.</p>
<p>Speaking of power-grabs, here is a chilling <a target='_blank' rel='noopener noreferrer'  href="https://www.economist.com/briefing/2020/03/26/rich-countries-try-radical-economic-policies-to-counter-covid-19">Economist article</a> about how the world will probably never be the same as countries move towards a new order.</p>
<blockquote>
<p><strong>&quot;But history suggests that a return to pre-covid days is unlikely. Two lessons stand out. The first is that governmental control over the economy takes a large step up during periods of crisis—and in particular war. The second is that the forces encouraging governments to retain and expand economic control are stronger than the forces encouraging them to relinquish it, meaning that a “temporary” expansion of state power tends to become permanent.&quot;</strong></p>
</blockquote>
<p>If you are playing on the side of the virus, and many people inadvertently are, a change of world order might not even seem  unexpected or even news since outright destruction and global scale genocide is not beyond the realms of possibilities. </p>
<p>In this regard, <a target='_blank' rel='noopener noreferrer'  href="https://www.ndemiccreations.com/en/22-plague-inc">Ndemic&#39;s Plague Inc</a>  been my favorite strategy cum simulation game for quite a while. It has become depressingly prophetic, just like Black Mirror, but in a much more precise manner.</p>
<blockquote>
<p><strong>I have been infecting and killing the entire global population on and off for 5+ years now. In different scenarios and with different pathogens, it has mostly been the case that</strong> </p>
</blockquote>
<ul>
<li>starting with low severity of symptoms and low fatality rate makes most of the governments ignore the looming crisis till its quite late</li>
<li>emergence of new kinds of symptoms at a later point, e.g. diarrhea, means that you can start killing effectively with those sweet, free and inevitable mutations</li>
<li>the poor countries receive the most deaths and damages in any outbreak</li>
<li>densely populated countries and low income countries are the best places of interest for your early days as you can infect most of the population without the governments noticing</li>
<li>regular hand washing and closing down of ship/air ports are always included in scenarios with higher difficulty level</li>
<li>investing in research labs and collaboration around the world is bad news for your win. </li>
<li>better infect and kill scientists when they still have too low of a budget to protect themselves and work even in rich countries and especially those leading the global research efforts</li>
<li>if you are getting out of control in EU/US, you are close to victory</li>
<li>if you have reached Greenland and Madagascar, you have probably also infected almost every other country. </li>
<li>it is also a great idea to start from remote countries like these or reach there early on</li>
<li>bioaerosol and zoonosis are your best friends</li>
<li>olympics and other mass events/festivals not getting canceled is a good sign that the people have chosen money at the cost of deaths</li>
<li>the news cycle is highly depressing and morbidly funny at the same time</li>
</ul>
<p>The key to our survival in this new <em>covidiocratic</em> world order would be to understand the signs and warnings we have had since many years, accept our past mistakes openly and move on together to fight the new <del>COVID-19</del> SARS virus. </p>
<p>Speaking of keys, I found myself quoting earlier to my friend the popular 3NF ideal, &quot;The key, the whole key and nothing but the key. So help me Codd&quot;. It reminded me that as computer scientists we don&#39;t shy away from <a target='_blank' rel='noopener noreferrer'  href="https://en.m.wikipedia.org/wiki/Lambda_calculus#%CE%B2-reduction_2">beta substituting</a> God. Or as developers of worlds and as gamers in those worlds, we roleplay as God. But we also see similar grandiose delusions among many public leaders gaming our current world with their unjustified decisions and power grabs. Now is the absolute wrong time to have God-delusions or taking power hungry measures alike those from our political and high positioned covidiots.</p>
<p>The key is probably to be less covidiotic and more human. </p>
<p>(This needs to be normalized way beyond Codd&#39;s normal forms.)</p>
]]></content:encoded></item><item><title><![CDATA[MAP III - Types of Types II]]></title><description><![CDATA[We need to invert the wasteful trend of learning something as timeless as higher maths only as a means to learn an ephemeral or ever-changing programming language or paradigm. Let's aim instead to explain and discuss foundational mathematical structu...]]></description><link>https://risav.dev/map-iii-types-of-types-ii</link><guid isPermaLink="true">https://risav.dev/map-iii-types-of-types-ii</guid><category><![CDATA[Scala]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[map]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Mon, 13 Apr 2020 20:21:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1587052018270/_BDRxWrpv.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong>We need to invert the wasteful trend of learning something as timeless as higher maths only as a means to learn an ephemeral or ever-changing programming language or paradigm. Let's aim instead to explain and discuss foundational mathematical structures like types and categories through these programming languages as visual learning aids. This helps us become better developers in any language, including new ones for quantum computing or even natural language-based programming.</strong>  </p>
</blockquote>
<p>Previously on <a target="_blank" href="https://risav.dev/map-iii-types-of-types-ck8lrxnlx011b79s17rbswwtq">MAP - Types of Types</a>, we looked at the type hierarchy of Scala and worked with a basic 'level 1' definition of types. Now we will level up and refine our previous working definition of types as value spaces with a set of allowed operations. At level 2, we will celebrate Function's tying of the knot with Data and how that adds a new dimension, literally as well, to how we have come to define and understand types. We will need to go back to discussing some basics like the very concept of functions and objects. With this slightly boring and unapologetically pedantic detour, we will demystify some commonly held oversimplifications or misconceptions and proceeds towards the more advanced and interesting concepts being on the same page. For instance we will see how functions and objects together create a fast track towards advanced abstract data types and algebraic structures or how classes and objects are simultaneously quite different and so much more than what we have been teaching our kids.</p>
<hr />
<h2 id="heading-2-function-weds-data-domain-and-co-domain-spaces">2. Function weds Data: Domain and Co-domain Spaces</h2>
<p>Our last definition of types was mainly concerned with types of data. It was therefore sufficient to think of value spaces, basic syntactics and behavior, understood in the sense of a set of operations on elements of that space. In programming, behavior comes from patterns of actions, which itself comes from operational chunks of code, which in turn act only on either data or other codes.</p>
<p>It's no surprise that chunks of programming instructions and of data have lived together on the same memory space ever since <a target="_blank" href="https://en.wikipedia.org/wiki/Von_Neumann_architecture">von Neumann architecture</a> was first adopted. This intimacy of data and code is lost on many programmers who do not often need to think of the nitty-gritty of the innards of their machines. </p>
<p>Functions and objects are two major constructs in programming where this intimacy-by-design is directly reflected at the level of program codes. Since they have already 'moved in' together, many languages including Scala makes this an official relationship, which I have cheekily phrased as 'function weds data'.</p>
<h3 id="heading-21-object-and-class">2.1 Object and Class</h3>
<p>Just like every construct in Scala has a type, every instance of a type is an object. Scala does not have Java-style primitive types, which do not have objects.</p>
<p>Whether or not a language follows <strong><em>object oriented programming</em></strong>, an object in a programming language is a data abstraction representing value(s) in memory. An object has a named identifier and may have properties, methods with read/write access to the object's properties and relationships with other objects. Alike functions, objects have mathematical counterparts too. We will explore them in the next two posts in this series.</p>
<h3 id="heading-templates">Templates</h3>
<p>A class is famously known as a 'blueprint' or template for instantiating an object. The class defines what properties, methods and relations an object can have and/or from where it inherits them. A class name is also usually the name of the user-defined type of the objects made using the class's constructor, which also usually has the same name as the class. </p>
<p>This is only partially true in Scala but wholly correct in Scala's more popular cousin Java. In Scala, it is problematic to hold on to the idea of class as a sole blueprint for objects. </p>
<p>The Scala specs define objects, classes and traits (Java 8+ interface-like abstractions supporting states, mix-in type restrictions, reference to objects of implementing classes) in terms of templates, which are not actually available for programmers. </p>
<blockquote>
<p><strong>Templates, not classes, are the actual templates in Scala.</strong></p>
</blockquote>
<p>A template definition may be a class template definition or an object template definition or a trait template definition. A class definition or an object definition may be for a regular class of objects or a singleton object or for a case class or a case singleton object. These template definitions are what actually define the type signature of the resulting objects and the constructors or initial values therein define the initial states of those objects. </p>
<p>This conception of class in Scala is, as with functions, closer to a class in mathematics in the sense that a class definition represents a constrained set of instantiable objects while an object definition is just for one object. </p>
<p>Scala also throws away the concept of static classes that do not need instantiation in favor of singleton objects created via the object template definition. These static classes, values and methods are hard to reconcile with the object oriented paradigm. They do not support inheritance and dynamic dispatch due to polymorphism, which itself is possible due to inheritance. Lastly they are also tough to mock and unit test easily.</p>
<h3 id="heading-meta">Meta</h3>
<p>A class may also instantiate other classes in some languages or object systems like Python, CLOS, Object Pascal, Smalltalk, Ruby, Objective C and C++. Such a class is called a metaclass. An object may also have a meta level or more above it. Such an object is called a metaobject. </p>
<p>As is usual with meta of anything, the metaclasses and metaobjects are parts of advanced concepts in programming. These are useful in understanding reflection, a programming construct's ability to introspect, augment or change its own behavior. In Scala this is achieved via Java's Reflection API and via natively added capabilities since Scala's 2.10 version. We will go on this reflective journey when we start the library developer tracks (L1 - L3) after having discussed the essential maths and concept behind the programmer's track (A1 - A3).</p>
<h3 id="heading-bonus-classless-oop">Bonus: Classless OOP</h3>
<p>However a class is not the only mechanism for defining templates for object instantiation. </p>
<p>Here's an <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">excerpt from MDN</a> regarding how JavaScript has OOP, better than most other languages known for their OOP, without classes. The ES6 classes are actually just syntactic sugar to make it easier for those used to class based OOP.</p>
<blockquote>
<p><strong>A prototype-based language?</strong></p>
<p><strong>JavaScript is often described as a prototype-based language — to provide inheritance, objects can have a prototype object, which acts as a template object that it inherits methods and properties from. An object's prototype object may also have a prototype object, which it inherits methods and properties from, and so on.</strong> </p>
<p><strong>This is often referred to as a prototype chain, and explains why different objects have properties and methods defined on other objects available to them.</strong>
<strong>Well, to be exact, the properties and methods are defined on the prototype property on the Objects' constructor functions, not the object instances themselves.</strong></p>
</blockquote>
<h3 id="heading-22-functions-and-methods">2.2 Functions and Methods</h3>
<p>A function is a chunk of code you can call by name. The function, its inputs and output can each be objects. In Scala, they always are.</p>
<h3 id="heading-inputs">Inputs:</h3>
<p>Functions may take values as inputs, possibly operate on these values or create side-effects based on those values or the context, and likely return something in the end. Pure functions however are more well behaved and closer to the functions from mathematics thanks to idempotence, referential transparency, and separation from side effects.</p>
<p>Informally speaking, the space of all possible values that could be accepted as an input is called the <em>domain</em> of a function.</p>
<blockquote>
<p><strong>Spaces are just sets with added structures. In our context, spaces may have varying dimensionality and each element has its own previously defined level 1 type.</strong></p>
</blockquote>
<h3 id="heading-outputs">Outputs:</h3>
<blockquote>
<p><strong>Every chunk of code in Scala that can be put on a single line returns a value.</strong></p>
</blockquote>
<p>These lines, which may be typed as blocks for readability, may be either functions or expressions that compose functions. In either case, an output per expression or per function is guaranteed. Even if an expression or function is handling side effects or running into an exception, the previously mentioned <code>Unit</code> return is guaranteed.</p>
<p>This style of programming with expressions is called <strong><em>expression oriented programming (EOP)</em></strong> and is a part of the <strong>functional programming</strong> paradigm.</p>
<p>Informally speaking, the space of all possible values that could be produced as an output is called the <em>co-domain</em> of a function.</p>
<hr />
<h3 id="heading-23-parameter-types-and-return-types">2.3 Parameter Types and Return Types</h3>
<p>Now that we are literally on the same page regarding the lingo and the concepts, let's take these concepts to meet some program codes.</p>
<p>Since every line is either a function or an expression, we can simply take note of what type of thing goes in and what comes out. </p>
<h3 id="heading-ifelse-ifelse-v1">if/else-if/else (v1)</h3>
<p>This is commonly needed and commonly avoidable expression. Let's break it down.</p>
<p>How could we write a (basic) version of the if-then expression? We know that it would </p>
<ul>
<li>take a predicate as the first parameter i.e. either a <code>Boolean</code> or something that returns a <code>Boolean</code> </li>
<li>take a function to execute if the above value is true as the second parameter</li>
<li>the predicate and the function could use any number of parameters of <code>Any</code> type</li>
</ul>
<pre><code class="lang-TypeScript"><span class="hljs-comment">// Naive if-then without advannced tytpes</span>

def ifThen(someBool: <span class="hljs-built_in">Boolean</span>)(func: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">Boolean</span>): Any = {
  !someBool || func()
}

def unitaryFunc() = {
  <span class="hljs-literal">false</span>
}

ifThen(<span class="hljs-literal">true</span>) (unitaryFunc)
<span class="hljs-comment">// res0: Any = false</span>
<span class="hljs-comment">// same as the invocation below</span>

ifThen(<span class="hljs-number">1</span> == <span class="hljs-number">2</span>) {unitaryFunc}
<span class="hljs-comment">// res1: Any = true</span>

ifThen(<span class="hljs-number">42</span> == <span class="hljs-number">42</span>) {unitaryFunc}
<span class="hljs-comment">// res2: Any = false</span>
</code></pre>
<p>This is quite a useless if-then in its current form but it gives us a good outline of how if-then works and what we should improve over the course of this series. </p>
<ul>
<li>As explained in 'Curly Braces and Parentheses' in <a target="_blank" href="https://risav.dev/viva-la-scala-ck8nu72vb029w79s179c38sza">Viva La Scala</a> explainer collection, the curly braces you see in if statements and other control structures are nothing more than just simple parentheses substituted for readability and multi-line blocks. </li>
<li>The if-then structure or <code>p -&gt; q</code> is logically equivalent to <code>¬p ∨ q</code></li>
</ul>
<p>In terms of improvements, these would be highly necessary:</p>
<ul>
<li>We will need to support more types of parameters and return values for the function being passed to the if-then function.</li>
<li>We will need to find a way to compose if-then to else-if and else constructs.</li>
</ul>
<p>Function composition requires that the return type of the function passed as a parameter is the same as the parameter type of the function receiving that function as its parameter. How then do you compose functions that need to support incompatible return and parameter types? We will later explore some solutions to this, including monadic ones. </p>
<p>Here's an an example of how Java's Optional is converted to the monadic version in Scala:</p>
<pre><code class="lang-TypeScript">def toScala[A](o: Optional[A]): Option[A] = <span class="hljs-keyword">if</span> (o.isPresent) Some(o.get) <span class="hljs-keyword">else</span> None
</code></pre>
<h3 id="heading-match-case">match-case</h3>
<p>The above example is fairly simple use case for if-else because the Optional container has a nice and simple <code>isPresent</code> method make it easier to test against a method with <code>Boolean</code> return type. However here's how the reverse condition is achieved by Scala:</p>
<pre><code class="lang-TypeScript"><span class="hljs-keyword">import</span> java.util.{Optional, OptionalDouble, OptionalInt, OptionalLong}
<span class="hljs-keyword">import</span> java.{<span class="hljs-function"><span class="hljs-params">lang</span> =&gt;</span> jl}

<span class="hljs-built_in">object</span> OptionConverters {

  def toJavaOptionalInt(o: Option[jl.Integer]): OptionalInt = o match {
    <span class="hljs-keyword">case</span> Some(a) =&gt; OptionalInt.of(a)
    <span class="hljs-keyword">case</span> <span class="hljs-function"><span class="hljs-params">_</span> =&gt;</span> OptionalInt.empty
  }
}
</code></pre>
<p>This time we are checking against the possible types. match-case is a better fit for checking against types, which in this case are either <code>Some</code> or anything else. </p>
<p>Note that the match construct is also an expression and the curly braces are once again super-powered parentheses which can take multiline values or functions or expressions as arguments.</p>
<p>The input to the match expression is <code>o</code> provided as the first operand in infix style and the <code>case</code> expressions provided together as the later parameter in the curly braces. The return type is determined by the return type of the expression on the right side of the matched case.</p>
<p>The match-case expression is also capable of checking against values and is especially better suited for cases with too many <code>case</code>s. </p>
<pre><code class="lang-TypeScript">def getEnglishNames(x: Int): <span class="hljs-built_in">String</span> = x match {
  <span class="hljs-keyword">case</span> <span class="hljs-number">0</span> =&gt; <span class="hljs-string">"Zero"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">1</span> =&gt; <span class="hljs-string">"One"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">2</span> =&gt; <span class="hljs-string">"Two"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">3</span> =&gt; <span class="hljs-string">"Three"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">4</span> =&gt; <span class="hljs-string">"Four"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">5</span> =&gt; <span class="hljs-string">"Five"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">6</span> =&gt; <span class="hljs-string">"Six"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">7</span> =&gt; <span class="hljs-string">"Seven"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">8</span> =&gt; <span class="hljs-string">"Eight"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-number">9</span> =&gt; <span class="hljs-string">"Nine"</span>
  <span class="hljs-keyword">case</span> <span class="hljs-function"><span class="hljs-params">_</span> =&gt;</span> <span class="hljs-string">"Not enough fingers!!"</span>
}

getEnglishNames(<span class="hljs-number">6</span>)
<span class="hljs-comment">// res0: String = Six</span>

getEnglishNames(<span class="hljs-number">10</span>)
<span class="hljs-comment">// res1: String = Not enough fingers!!</span>
</code></pre>
<p>How about mixing these two expressions? If you have a use case where you have to check for values while also checking for types, it's best to use both. Here's how Scala converts <code>FiniteDuration</code> to a Java duration:</p>
<pre><code class="lang-TypeScript">  def toJava(duration: FiniteDuration): JDuration = {
    <span class="hljs-keyword">if</span> (duration.length == <span class="hljs-number">0</span>) JDuration.ZERO
    <span class="hljs-keyword">else</span> duration.unit match {
      <span class="hljs-keyword">case</span> TimeUnit.NANOSECONDS =&gt; JDuration.ofNanos(duration.length)
      <span class="hljs-keyword">case</span> TimeUnit.MICROSECONDS =&gt; JDuration.of(duration.length, ChronoUnit.MICROS)
      <span class="hljs-keyword">case</span> TimeUnit.MILLISECONDS =&gt; JDuration.ofMillis(duration.length)
      <span class="hljs-keyword">case</span> TimeUnit.SECONDS =&gt; JDuration.ofSeconds(duration.length)
      <span class="hljs-keyword">case</span> TimeUnit.MINUTES =&gt; JDuration.ofMinutes(duration.length)
      <span class="hljs-keyword">case</span> TimeUnit.HOURS =&gt; JDuration.ofHours(duration.length)
      <span class="hljs-keyword">case</span> TimeUnit.DAYS =&gt; JDuration.ofDays(duration.length)
    }
  }
</code></pre>
<p>These are pre-existing types. Can we do this with custom types? As we discussed, custom types could come from custom objects or classes. You might have also noticed earlier that class and object template definitions may also have a <code>case</code> qualifier in front of it.</p>
<pre><code class="lang-JavaScript">sealed abstract <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Device</span>
<span class="hljs-title">case</span> <span class="hljs-title">class</span> <span class="hljs-title">IPhoneX</span>(<span class="hljs-title">uglyNotchSize</span>: <span class="hljs-title">Long</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Device</span>
<span class="hljs-title">case</span> <span class="hljs-title">class</span> <span class="hljs-title">S10</span>(<span class="hljs-title">holeCamOffset</span>: <span class="hljs-title">Double</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Device</span>
<span class="hljs-title">case</span> <span class="hljs-title">class</span> <span class="hljs-title">NexS</span>(<span class="hljs-title">popUpCam</span>: <span class="hljs-title">Boolean</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Device</span>
<span class="hljs-title">case</span> <span class="hljs-title">class</span> <span class="hljs-title">Pixel</span>(<span class="hljs-title">pixels</span>: <span class="hljs-title">Int</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Device</span> </span>{
  def sorry = <span class="hljs-string">"Old School"</span>
}

def howBeautiful(device: Device): <span class="hljs-built_in">String</span> = device match {
  <span class="hljs-keyword">case</span> IPhoneX(_) =&gt; <span class="hljs-string">"Ugly"</span>
  <span class="hljs-keyword">case</span> S10(offset) <span class="hljs-keyword">if</span> offset == <span class="hljs-number">0.5</span> =&gt; <span class="hljs-string">"Symmetric but Meh"</span>
  <span class="hljs-keyword">case</span> S10(_) =&gt; <span class="hljs-string">"Meh"</span>
  <span class="hljs-keyword">case</span> NexS(<span class="hljs-literal">false</span>) =&gt; <span class="hljs-string">"Cool"</span>
  <span class="hljs-keyword">case</span> NexS(<span class="hljs-literal">true</span>) =&gt; <span class="hljs-string">"Clunky"</span>
  <span class="hljs-keyword">case</span> px: <span class="hljs-function"><span class="hljs-params">Pixel</span> =&gt;</span> px.sorry
}


howBeautiful(IPhoneX(<span class="hljs-number">10</span>))
<span class="hljs-comment">// res0: String = Ugly</span>
howBeautiful(S10(<span class="hljs-number">0.5</span>))
<span class="hljs-comment">// res1: String = Symmetric but Meh</span>
howBeautiful(S10(<span class="hljs-number">0.7</span>))
<span class="hljs-comment">// res2: String = Meh</span>
howBeautiful(NexS(<span class="hljs-literal">false</span>))
<span class="hljs-comment">// res3: String = Cool</span>
howBeautiful(NexS(<span class="hljs-literal">true</span>))
<span class="hljs-comment">// res4: String = Clunky</span>
howBeautiful(Pixel(<span class="hljs-number">4</span>))
<span class="hljs-comment">// res5: String = Old School</span>
</code></pre>
<p>The <code>sealed</code> keyword tells Scala that all possible subtypes or <code>case</code>s are present within the same file and not dispersed elsewhere in the code. </p>
<p>The <code>if</code> statement on the first S10 <code>case</code> is another way you could mix <code>if</code> with <code>match</code>. In this <code>case</code>, it is called a pattern guard. </p>
<p>Notice that the ordering of the <code>case</code>s matters because the fall through is similar to that found in <code>switch</code> statements in other languages.</p>
<p>Also note that all but the last <code>case</code> are still checking against values albeit of value objects. Only the last <code>case</code> is actually checking against a user defined type.</p>
<p>We now have a good groundwork to look into try-catch and try-success-failure. We will also be looking into for, for-yield and foreach expressions once we have collection types in our arsenal by the end of the next post. That is also where Scala/Mathematics concepts start to get real fun to play with. </p>
<h1 id="heading-next-on-types-of-types">Next on 'Types of Types'</h1>
<p>To keep the posts from going beyond optimal lengths, we will explore each of the next 'levels' of understanding and defining types in their own posts. Here's a sneak peek. </p>
<h2 id="heading-3-abstract-data-types-types-with-structure-and-behavior">3. Abstract Data Types: Types with Structure and Behavior</h2>
<p>Here we will rediscover the good old data structures mostly used in programming through a more formal, functional and scala-ble lens 🧐. Sum and product types will also pave the way for the more involved algebraic data types in the later section.</p>
<h3 id="heading-31-sum-and-product-types">3.1 Sum and Product Types</h3>
<ul>
<li>3.1.1 Union <em>or</em> Tagged Union</li>
<li>3.1.2 Tuple <em>and</em> Record</li>
</ul>
<h3 id="heading-32-set-and-list">3.2 Set and List</h3>
<ul>
<li>3.2.1 Unordered and Non-duplicated</li>
<li>3.2.2 Ordered and Random Accessible</li>
</ul>
<h3 id="heading-33-maps">3.3 Maps</h3>
<h3 id="heading-34-stack-and-queue">3.4 Stack and Queue</h3>
<h3 id="heading-35-graph-and-tree">3.5 Graph and Tree</h3>
<hr />
<h2 id="heading-4-algebraic-data-types-and-hkts">4. Algebraic Data Types and HKTs</h2>
<p>Here we will (re-)discover universal algebra, ring-like, group-like, lattice-like, module-like, and algebra-like algebraic structures relevant to advanced functional and reactive programming. We will also demystify higher kinded types and similarly exotic higher order concepts. </p>
<hr />
<h2 id="heading-5-a-gentle-introduction-to-category-theory">5. A Gentle Introduction to Category Theory</h2>
<p>Here we will use the Scala concepts and Type Theory topics thus far to go for a deep dive into Bartoz Milewski's excellent <a target="_blank" href="https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/">course on Category Theory </a>.</p>
<hr />
<p><strong>Further resources:</strong></p>
<ul>
<li><p>2.1 Classes and Objects Specs in Scala: https://scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html</p>
</li>
<li><p>2.2 Scala source code: https://github.com/scala/scala/blob/2.13.x/src/library/scala/</p>
</li>
</ul>
<hr />
<ul>
<li><p>1.1 D. L. Parnas, John E. Shore, David Weiss: Abstract types defined as classes of variables, https://dl.acm.org/doi/10.1145/942574.807133</p>
</li>
<li><p>1.2 Tony Hoare on his infamous billion dollar mistake: https://www.youtube.com/watch?v=kz7DfbOuvOM</p>
</li>
<li><p>1.3 Official Scala API Docs and resources: https://www.scala-lang.org/</p>
</li>
<li><p>1.4 L.G. Meredith, Pro Scala: Monadic Design Patterns for the Web: http://patryshev.com/books/GregoryMeredith.pdf</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Viva la Scala]]></title><description><![CDATA[Scala is a very scalable language. It actually is  true to its portmanteau name. But scalability is a double-edged sword.
With great scalability, comes great extensibility. And confusion. Lots and lots of confusions. 
We will have a look at a curated...]]></description><link>https://risav.dev/viva-la-scala</link><guid isPermaLink="true">https://risav.dev/viva-la-scala</guid><category><![CDATA[Scala]]></category><category><![CDATA[basics]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Mon, 06 Apr 2020 02:09:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1586138789775/-p3uZWXe_.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Scala is a very <em>scalable language</em>. It actually is  true to its portmanteau name. But scalability is a double-edged sword.</p>
<p>With great scalability, comes great extensibility. And confusion. Lots and lots of confusions. </p>
<p>We will have a look at a curated list of Scala's extensibility features. I have also noticed possible sources of confusions about Scala's syntax in my earlier post even though I was writing merely about the basics of Scala's type system.  </p>
<p>Fortunately, Scala's syntax can be easily understood with an hour or less of on <a target="_blank" href="https://docs.scala-lang.org/tour/basics.html">'Tour of Scala'</a> on the official site. An even shorter intro for people with Java, Kotlin or TypeScript experience can be found on just the [wikipedia page for Scala](https://en.wikipedia.org/wiki/Scala_(programming_language) of all places. </p>
<p>For further convenience, we will put together an ensemble of simple explainers of Scala's unique principles, features and syntax here. These are mainly going to be from the above links and the further reading links listed in the previous article. </p>
<p>Speaking of staying true to its name, this post itself will be a living document that we shall together keep updated. I hope we can form a one stop shop for picking up essential notes on Scala concepts and syntax details to get started. Explainers on control structures, types and advanced features will also be welcome. However we might need to put those ones elsewhere in the MAP series or the Play with Spring series if they are not already covered.</p>
<p>Viva la Scala!</p>
<h2 id="heading-unified-type-system">Unified Type System</h2>
<p>As we discussed before in MAP 3: Types of Types, every type in Scala has the top type <code>Any</code> as its supertype and the bottom type <code>Nothing</code> as its subtype.</p>
<blockquote>
<p>In Scala, all types inherit from a top-level class <code>Any</code>, whose immediate children are <code>AnyVal</code> (value types, such as <code>Int</code> and <code>Boolean</code>) and <code>AnyRef</code> (reference types, as in Java). This means that [...] in Scala, boxing and unboxing is completely transparent to the user. Scala 2.10+ allows for new value types to be defined by the user.</p>
</blockquote>
<h2 id="heading-uniform-access-principle">Uniform Access Principle</h2>
<p>This principle originally proposed by the computer scientist Bertrand Meyer, creator of Eiffel language, states that </p>
<blockquote>
<p>"All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation". </p>
</blockquote>
<p>In Scala it essentially translates to stipulating that calling an attribute, pre-computed property, method of an object etc all look the same syntactically. The semantics may defer as needed. For instance, even though values are evaluated only once, methods are evaluated each time they are invoked.</p>
<blockquote>
<p>Function or method <code>foo()</code> can also be called as just <code>foo</code>; method <code>thread.send(signo)</code> can also be called as just <code>thread send signo</code>; and method <code>foo.toString()</code> can also be called as just <code>foo toString</code></p>
</blockquote>
<h2 id="heading-dot-free-and-point-free">Dot Free and Point Free</h2>
<p>As we saw in the above uniform access section, Scala supports a dot free notation for calling methods and members. </p>
<blockquote>
<p>Any method can be used as an infix operator, e.g. "%d apples".format(num) and "%d apples" format num are equivalent. </p>
</blockquote>
<p>'Dot free' notation is not to be confused with <a target="_blank" href="https://en.wikipedia.org/wiki/Tacit_programming">'point free'</a> notation or tacit programming style in which function definitions do not identify the arguments (or 'points' in topology terms). This style allows for concise syntax, focus on functions instead of data, easier function composition and currying, among other things. As of the time of writing, using point free style in Scala for anything but trivial pieces of code would not be advised. </p>
<pre><code class="lang-TypeScript"><span class="hljs-comment">//verbose </span>
List(<span class="hljs-string">"dot"</span>, <span class="hljs-string">"free"</span>, <span class="hljs-string">"vs"</span>, <span class="hljs-string">"point"</span>, <span class="hljs-string">"free"</span>).foreach(<span class="hljs-function"><span class="hljs-params">s</span> =&gt;</span> println(s))

<span class="hljs-comment">//dot free</span>
List(<span class="hljs-string">"dot"</span>, <span class="hljs-string">"free"</span>, <span class="hljs-string">"vs"</span>, <span class="hljs-string">"point"</span>, <span class="hljs-string">"free"</span>) foreach {println(_)}

<span class="hljs-comment">//point free version:</span>
List(<span class="hljs-string">"dot"</span>, <span class="hljs-string">"free"</span>, <span class="hljs-string">"vs"</span>, <span class="hljs-string">"point"</span>, <span class="hljs-string">"free"</span>) foreach println
</code></pre>
<p>It is not easy for Scala to infer types when you use this parameter free style due to its local type inference system. If you are familiar with Haskell or SML with an essentially global Hindley-Milner type system, these are the kinds of type system super powers you will miss in Scala.</p>
<h2 id="heading-infix-and-symbolic-operators">Infix and Symbolic Operators</h2>
<p>In the expression <code>+1</code>, <code>+</code> is a prefix and also a unary operator. But when adding two <code>Int</code>s as in <code>1 + 2</code>, <code>+</code> is an infix operator defined for Scala's integer type. <code>+</code> is a bona-fide method name in Scala defined separately for all Scala types where addition makes sense. This includes <code>BigInt</code> and <code>BigDecimal</code> types too unlike in Java where arithmetic operations for Big* types cannot use the arithmetic operators <code>+</code>, <code>-</code>, <code>/</code>, and <code>*</code>. </p>
<p>As we saw in the dot free and point free example, methods can be treated as infix operators. </p>
<blockquote>
<p>In fact, arithmetic operators like <code>+</code> and <code>&lt;&lt;</code> are treated just like any other methods, since function names are allowed to consist of sequences of arbitrary symbols (with a few exceptions made for things like parens, brackets and braces that must be handled specially); the only special treatment that such symbol-named methods undergo concerns the handling of precedence.</p>
</blockquote>
<p>There are no postfix operators like <code>++</code> or <code>--</code> in Scala. The value types in Scala are immutable by default so you cannot just add these to them without breaking the type system. If you happen to need the mutable <code>var</code> variables for a value type, you can just use <code>+=</code> or <code>-=</code> like <code>counter += 1</code>. You can also use <code>*=</code> or <code>/=</code>.</p>
<h2 id="heading-setters-and-getters">Setters and Getters</h2>
<p>This one is for allowing setters and getters.</p>
<blockquote>
<p>Class body variables can be transparently implemented as separate getter and setter methods. For <code>trait FooLike { var bar: Int }</code>, an implementation may be </p>
</blockquote>
<pre><code class="lang-TypeScript"><span class="hljs-built_in">object</span> Foo <span class="hljs-keyword">extends</span> FooLike { 
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> x = <span class="hljs-number">0</span>; 
  def bar = x; 
  def bar_=(value: Int) { x = value }} } }
</code></pre>
<blockquote>
<p>The call site will still be able to use a concise foo.bar = 42.</p>
</blockquote>
<h2 id="heading-apply-and-update">Apply and Update</h2>
<p>This one allows for simple creation of collections, case classes or complex objects without having to <code>new</code> up a new instance, usually an empty one and then populate it next. It is also handy for defining default <code>apply</code> and <code>update</code> behaviors that make sense for your class.</p>
<blockquote>
<p>Methods <code>apply</code> and <code>update</code> have syntactic short forms. <code>foo()</code> — where <code>foo</code> is a value (singleton object or class instance) — is short for <code>foo.apply()</code>, and <code>foo() = 42</code> is short for <code>foo.update(42)</code>. 
Similarly, <code>foo(42)</code> is short for <code>foo.apply(42)</code>, and <code>foo(4) = 2</code> is short for <code>foo.update(4, 2)</code>. This is used for collection classes and extends to many other cases, such as STM cells.</p>
</blockquote>
<h2 id="heading-curly-braces-and-parentheses">Curly Braces and Parentheses</h2>
<blockquote>
<p>The use of curly braces instead of [or after] parentheses is allowed in method calls. This allows pure library implementations of new control structures. [...] 
<code>Vector.fill(4) { math.random }</code> is the same as <code>Vector.fill(4)(math.random)</code>. The curly braces variant allows the expression to span multiple lines.
<code>breakable { ... if (...) break() ... }</code> looks as if <code>breakable</code> was a language defined keyword, but really is just a method taking a thunk argument.</p>
</blockquote>
<h2 id="heading-colon-oscopy"><em>Colon-oscopy</em></h2>
<p>This one is for inline list creation and for colon-suffixed methods to be invoked in the order that looks intuitive:</p>
<blockquote>
<p>Method names ending in colon <code>:</code> expect the argument on the left-hand-side and the receiver on the right-hand-side. For example, the <code>4 :: 2 :: Nil</code> is the same as <code>Nil.::(2).::(4)</code>, the first form corresponding visually to the result (a list with first element 4 and second element 2).</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[MAP - III : Types of Types]]></title><description><![CDATA[We need to invert the wasteful trend of learning something as timeless as higher maths only as a means to learn an ephemeral or ever-changing programming language or paradigm. Let's aim instead to explain and discuss foundational mathematical structu...]]></description><link>https://risav.dev/map-iii-types-of-types</link><guid isPermaLink="true">https://risav.dev/map-iii-types-of-types</guid><category><![CDATA[Scala]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[Type Theory]]></category><dc:creator><![CDATA[Risav Karna]]></dc:creator><pubDate>Sat, 04 Apr 2020 15:30:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1586011891873/mFs7ElIw3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong>We need to invert the wasteful trend of learning something as timeless as higher maths only as a means to learn an ephemeral or ever-changing programming language or paradigm. Let's aim instead to explain and discuss foundational mathematical structures like types and categories through these programming languages as visual learning aids. This helps us become better developers in any language, including new ones for quantum computing or even natural language-based programming.</strong>  </p>
</blockquote>
<p>When talking about types in computer science, we could be talking about two types of types. Types from type theory are closely related to the types from from type systems used in programming languages. Both of these are fun and playing with them illuminates how any language works. It may even help you obtain A3 or perhaps even <a target="_blank" href="https://www.scala-lang.org/old/node/8610">L3-tier</a> superpowers.</p>
<p>Previously in the <a target="_blank" href="https://risav.dev/mathematics-anarchitecture-and-processes-ck5nahog004z4qps1w98ldfz0">Mathematics' (An)architecture and Processes (MAP) series</a>, we have briefly touched upon Curry-Howard-Lambek isomorphism, which is a trifecta of independent realizations about, among other things, how propositions are types i.e. claims that are true or false, formal proofs, logical calculus' constraints and formulae are types too. With Scala's types, and Java 11+'s and TypeScript's later, we will see what it actually means to say something as abstract as 'propositions are types' and why understanding these esoteric and zen sayings can make you a better programmer - in any language, with any kind of type system.</p>
<p>For getting started with types, we will come up with our working definition of types with increasing levels of technical depth. We will also be iteratively refining our definition and intuitions regarding what types are. As for how types look in programming, here are four simple examples:</p>
<pre><code class="lang-TypeScript">
val obligatory = <span class="hljs-string">"Hello World! "</span>  
<span class="hljs-comment">// type inferred to be String based on its value</span>

val goodbye : <span class="hljs-built_in">String</span> = <span class="hljs-string">"Goodbye, cruel world..."</span> 
<span class="hljs-comment">// type explicitly defined to be a String</span>

val emoji: Char = <span class="hljs-string">'☺'</span>
<span class="hljs-comment">// Unicode characters are present in Char type's value space</span>

val heteroList: List[Any] = List(obligatory + goodbye, <span class="hljs-literal">true</span>, <span class="hljs-number">42</span>)
<span class="hljs-comment">// String type allows addition operation </span>
<span class="hljs-comment">// The composed type List[Any] allows use of any type in heteroList</span>
</code></pre>
<p>This is certainly just a picture and certainly not the whole picture. However we will get closer to types through this kind of programmatic representation of types above.</p>
<blockquote>
<p><img src="https://upload.wikimedia.org/wikipedia/en/b/b9/MagrittePipe.jpg" alt="thisIsNotAPipe" /></p>
<p><em>This is not a pipe. This is just a representation of a pipe.</em></p>
</blockquote>
<p>Almost every programming construct that you can use has a type. It follows that there are many types of types.</p>
<h2 id="heading-1-common-data-types-syntactic-and-semantic-bits">1. Common Data Types: Syntactic and Semantic bits</h2>
<p>Let's start with the primitive ones. Types of values in data are the easiest to intuitively understand. Here at level 1, we will define type as a pre-defined value space for our data which possibly comes along with a set of allowed operations on the values in that value space.</p>
<p>At level 1, you may find, for instance, a type that does not have any possible operations or one that is simply an alias of another type. These are merely syntactic types. All types have this syntactic aspect in the sense that a type definition ensures the program compiler - and the programmer - that it adheres to the rules and constraints set by the programming language itself, especially regarding what is and isn't allowed to be done with a certain variable or construct.</p>
<p>For instance, if you find a type definition called <code>Money</code> in your program, it probably is a syntactic sugar representing some type of fixed or floating point numbering.</p>
<p>The semantic aspect of a type would be about what it means to have a certain type in the first place. For instance, type semantics could tell you what possible actions are possible on that type or what interactions are allowed with other types. </p>
<p>For a utility type like <code>Money</code>, the operations could be inherited arithmetic methods for addition or subtraction or convenience methods composed of other operations like methods for interest rate calculations.</p>
<hr />
<h3 id="heading-any-and-nothing"><strong>Any and Nothing</strong></h3>
<p>All types in Scala are different  derivations of the <code>Any</code> type. Informally, you may call it the mother of all types as it is the <strong>top type</strong> in Scala's type hierarchy.</p>
<p><code>Any</code> of Scala is similar to the <code>Object</code> type defined by the class also named <code>Object</code> in Java. In TypeScript, there are two top types <code>any</code> and <code>unknown</code>. <code>any</code> just tells the TypeScript compiler that it should not even bother to do any type checks. So compile time type safety due to aforementioned type syntactics and semantics is effectively disabled for that variable or constant of <code>any</code> type. So related bugs may only be discovered if unexpected operations are performed on that value at runtime - during testing (hopefully) or in production (yikes). <code>unknown</code> type signifies that the actual type is yet unknown but can be narrowed down and pin-pointed based on its runtime values, usually using a language construct called type guards. </p>
<p><code>Any</code> in Scala has general definitions of <code>equals</code>, <code>hashCode</code> and <code>toString</code> methods. This means that <code>Any</code> type in Scala allows for checking whether anything equals another and what its hashed or string representation is. </p>
<blockquote>
<p>All puns intended. Always.</p>
</blockquote>
<p>Type theory and category theory, from which we have type systems in programming, also have something called a <strong>bottom type</strong>. It is called so because it is at the bottom of the type hierarchy i.e. all types have the bottom type as their subtype. Scala's bottom type is called <code>Nothing</code> as there is nothing you can assign to a variable or construct of type <code>Nothing</code>. If a function throws an exception instead of returning any value, it has <code>Nothing</code> for a return type. We will find further uses of this in later posts, especially when we discuss covariance under parametric polymorphism.</p>
<hr />
<h3 id="heading-anyval-and-anyref"><strong>AnyVal and AnyRef</strong></h3>
<p>In programming, you may be directly using or passing around a value from one memory location to another. These types of values are derived from <code>AnyVal</code> type in Scala, which itself is a descendant derived directly from the <code>Any</code> supertype.</p>
<p>You may also just be referring to where the value is located in your memory space instead of moving those values around. These variables have a reference type, which descends from the <code>AnyRef</code> supertype, which itself descends directly from the <code>Any</code> type.</p>
<p>When you look at the documentation for a type, for example <a target="_blank" href="https://www.scala-lang.org/api/current/scala/Boolean$.html">Boolean</a>, you might find methods that <code>box</code> or <code>unbox</code> a value. The <code>scala.Boolean</code> is a value type but you can wrap your boolean value inside a 'box' made of <code>java.lang.Boolean</code>, which is a reference type. You might need to do this boxing to access reference type's methods or, in this case, to ensure interoperability with Java clients of your library. Similarly, you can also 'unbox' a reference type into a value type.</p>
<hr />
<h3 id="heading-unit-and-boolean"><strong>Unit and Boolean</strong></h3>
<p>Just like <code>Nothing</code> allows nothing as its value, <code>Unit</code> allows only one and the same value, and <code>Boolean</code> allows only two.</p>
<p><code>Boolean</code> type is probably the most well known and easily understood of all. It allows its value to be either <code>true</code> or <code>false</code>. </p>
<p><code>Unit</code> type only allows one value, which is written as <code>()</code>. Therefore it holds no information and is very similar to, but not the same as, <code>void</code> used in C/C++/Java. It also should not be confused with aforementioned <code>Nothing</code> or with <code>Null</code> from the next section. We will return back to this type later when we talk about tuples and product types since <code>Unit</code> can be interpreted as a 0-tuple or a product of no types. We will also see how it is useful when we talk about abstract data types and algebraic data types.    </p>
<hr />
<h3 id="heading-option-and-null"><strong>Option and Null</strong></h3>
<p>Sometimes a reference is likely to point either to some value or none of it when the value of the instance of that type is requested for use by the program execution. In many languages, such references lead to a null pointer, which Tony Hoare, the pioneering computer scientist who introduced the null pointer concept, has famously called his billion dollar mistake. </p>
<p>The functional and type safe solution to this annoyance would be the the type <code>Option</code> or <code>Optional</code> (in Java, Scala, Kotlin, Swift, SML, OCaml, Rust) or <code>Maybe</code> (in Haskell, Agda, Idris). Depending on the implementation, this type may be <a target="_blank" href="https://books.underscore.io/scala-with-cats/scala-with-cats.html#what-is-a-monad">monadic</a>.</p>
<p>In Scala, <code>Option</code> is a monadic type and has two subtypes <code>Some</code> or <code>None</code>. We will discuss monads in the section on algebraic data types. For now, going by the above box or container metaphor, if you think that in your variable there <em>maybe some</em> value or <em>optionally none</em> at all then you can put it inside an <code>Option</code> box. To check if there are any <em>valuables</em> in the box, you can simply check the type of the content instead of various <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Truthy">'falsiness' checks</a> or nullness checks on the value of the content itself. The type is is guaranteed to be <code>Some</code> if something is present or <code>None</code> otherwise. There also exists another similar trio called <code>Try</code>, <code>Success</code> and <code>Failure</code> in Scala. They essentially form a more concise syntax and are used when catching exceptions could be needed as opposed to just dealing with presence or absence of values. </p>
<p>We will explore examples of the usage of both of these trios when we later discuss pattern matching based on types and control flow structures like try-catch, match-case or for-yield. </p>
<hr />
<h3 id="heading-the-normie-types"><strong>The <em>Normie</em> Types</strong></h3>
<p>These are the common, necessary but boring types that will become interesting when we start composing them with other types and weaving mind-bending - and hopefully helpful - structures later.</p>
<h4 id="heading-i-byte-short-and-int">I. Byte, Short and Int</h4>
<p>These types have trivially defined value spaces. Available methods for each type will defer as relevant.</p>
<pre><code class="lang-TypeScript">val u = <span class="hljs-number">42</span>  <span class="hljs-comment">// defaults to Int type</span>
val b: Byte = <span class="hljs-number">1</span> <span class="hljs-comment">// (-2^7 to 2^7-1] i.e. -128 to 127</span>
val s: Short = <span class="hljs-number">2</span> <span class="hljs-comment">// (-2^15 to 2^15-1] i.e. -32,768 to 32,767</span>
val i: Int = <span class="hljs-number">3</span> <span class="hljs-comment">// (-2^31 to 2^31-1] i.e. -2,147,483,648 to 2,147,483,647</span>
</code></pre>
<h4 id="heading-ii-long-float-and-double">II. Long, Float and Double</h4>
<p>These are pretty much the same as the above numerical types except they allow for bigger ranges and, in case of <code>Float</code> and <code>Double</code>, fractional values with floating point precision.</p>
<pre><code class="lang-TypeScript">val l: Long = <span class="hljs-number">1</span> <span class="hljs-comment">// (-2^63 to 2^63-1] </span>
val f: Float = <span class="hljs-number">2.0</span> <span class="hljs-comment">// 32-bit IEEE 754 single-precision float</span>
<span class="hljs-comment">// 1.40129846432481707e-45 to 3.40282346638528860e+38</span>
val d: Double = <span class="hljs-number">3.0</span> <span class="hljs-comment">// 64-bit IEEE 754 double-precision float</span>
<span class="hljs-comment">// 4.94065645841246544e-324d to 1.79769313486231570e+308d</span>
</code></pre>
<h4 id="heading-iii-char-and-string">III. Char and String</h4>
<p>A <code>Char</code> is a literal from the Unicode charset. A <code>Char</code> can be cast to its corresponding position in the Unicode charset as an <code>Int</code>, like you can in most languages.</p>
<pre><code class="lang-TypeScript">scala&gt; val c: Char = <span class="hljs-string">'q'</span>
c: Char = q

scala&gt; val i: Int = c
i: Int = <span class="hljs-number">113</span>

scala&gt; val emoji: Char = <span class="hljs-string">'☺'</span>
emoji: Char = ☺

scala&gt; emoji.toInt
res0: Int = <span class="hljs-number">9786</span>
</code></pre>
<p>A <code>String</code> is defined as a sequence of <code>Char</code>s. You assign a string using quotes:</p>
<pre><code class="lang-TypeScript">
val strQ = <span class="hljs-string">"Now I am become Death, the destroyer of worlds - J. Robert Oppenheimer"</span>

val listToStr = List(<span class="hljs-string">"If I'm not back in five minutes"</span>, <span class="hljs-string">"just wait longer"</span>).toString
<span class="hljs-comment">// output: List(If I'm not back in five minutes, just wait longer)</span>
</code></pre>
<p>Scala <code>String</code> relies on <code>java.lang.String</code> but is also augmented by many useful utility methods from the <code>StringOps</code> class. </p>
<blockquote>
<p>It is not necessary to learn these methods or those of any Scala type by heart. You should just get more intimate with the docs and always check the docs before writing a routine or standard looking operation on your own. You can likely also discover them using your IDE's autocomplete or inline documentations. </p>
</blockquote>
<h4 id="heading-iv-the-big-and-the-rich">IV. The Big and The Rich</h4>
<p>There are <code>StringOps</code> equivalents for the other the other value types called <code>RichBoolean</code>, <code>RichByte</code>, <code>RichChar</code>, <code>RichDouble</code>, <code>RichFloat</code>, <code>RichInt</code>, <code>RichLong</code> and <code>RichShort</code>. These <a target="_blank" href="http://w3sdesign.com/?gr=s07&amp;ugr=proble">proxies</a> provide additional methods to the above value types. Unlike the case in Java with its primitive and boxed reference types, this pattern allows for keeping the value types lightweight while still providing a rich API and therefore fewer use cases for boxing and unboxing due to performance vs convenience trade-offs.</p>
<p>Besides the <code>Rich</code>* ones, <code>scala.math</code> package provides <code>BigDecimal</code> and <code>BigInt</code> classes. These are for calculations with floating-point numbers of arbitrary precision starting with a default precision approximately that of IEEE 128-bit floating point numbers.</p>
<hr />
<h1 id="heading-next-on-types-of-types">Next on 'Types of Types'</h1>
<p>To keep the posts from going beyond optimal lengths, we will explore each of the next 'levels' of understanding and defining types in their own posts. Here's a sneak peek. </p>
<h2 id="heading-2-function-weds-data-domain-and-co-domain-spaces">2. Function weds Data: Domain and Co-domain Spaces</h2>
<p>Here we will introduce functions and methods together with objects and classes. We will see how OOP augments the power of functional programming and how best to avoid the many pitfalls of OOP.</p>
<h3 id="heading-21-object-and-class">2.1 Object and Class</h3>
<h3 id="heading-22-functions-and-methods">2.2 Functions and Methods</h3>
<h3 id="heading-23-parameter-types-and-return-types">2.3 Parameter Types and Return Types</h3>
<hr />
<h2 id="heading-3-abstract-data-types-types-with-structure-and-behavior">3. Abstract Data Types: Types with Structure and Behavior</h2>
<p>Here we will rediscover the good old data structures mostly used in programming through a more formal, functional and scala-ble lens 🧐. Sum and product types will also pave the way for the more involved algebraic data types in the later section.</p>
<h3 id="heading-31-sum-and-product-types">3.1 Sum and Product Types</h3>
<ul>
<li>3.1.1 Union <em>or</em> Tagged Union</li>
<li>3.1.2 Tuple <em>and</em> Record</li>
</ul>
<h3 id="heading-32-set-and-list">3.2 Set and List</h3>
<ul>
<li>3.2.1 Unordered and Non-duplicated</li>
<li>3.2.2 Ordered and Random Accessible</li>
</ul>
<h3 id="heading-33-maps">3.3 Maps</h3>
<h3 id="heading-34-stack-and-queue">3.4 Stack and Queue</h3>
<h3 id="heading-35-graph-and-tree">3.5 Graph and Tree</h3>
<hr />
<h2 id="heading-4-algebraic-data-types-and-hkts">4. Algebraic Data Types and HKTs</h2>
<p>Here we will (re-)discover universal algebra, ring-like, group-like, lattice-like, module-like, and algebra-like algebraic structures relevant to advanced functional and reactive programming. We will also demystify higher kinded types and similarly exotic higher order concepts. </p>
<hr />
<h2 id="heading-5-a-gentle-introduction-to-category-theory">5. A Gentle Introduction to Category Theory</h2>
<p>Here we will use the Scala concepts and Type Theory topics thus far to go for a deep dive into Bartoz Milewski's excellent <a target="_blank" href="https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/">course on Category Theory </a>.</p>
<p>Beware that category theorists are sometimes insufferable and gave birth to memes like this <a target="_blank" href="http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html?m=1">one</a>: </p>
<blockquote>
<p>'A monad is just a monoid in the category of endofunctors, what's the problem?' </p>
</blockquote>
<p>or this one below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1586014084969/1Kio9oLYO.png" alt="meme_category_theory.png" /></p>
<hr />
<p><strong>Further resources:</strong></p>
<ol>
<li><p>D. L. Parnas, John E. Shore, David Weiss: Abstract types defined as classes of variables, https://dl.acm.org/doi/10.1145/942574.807133</p>
</li>
<li><p>Tony Hoare on his infamous billion dollar mistake: https://www.youtube.com/watch?v=kz7DfbOuvOM</p>
</li>
<li><p>Official Scala API Docs and resources: https://www.scala-lang.org/</p>
</li>
<li><p>L.G. Meredith, Pro Scala: Monadic Design Patterns for the Web: http://patryshev.com/books/GregoryMeredith.pdf</p>
</li>
</ol>
<p>Cover image stolen from: https://medium.com/@olxc/the-evolution-of-a-scala-programmer-1b7a709fb71f</p>
]]></content:encoded></item></channel></rss>