Scalable architectures / Code management, tip 1: imperative vs declarative
Tags: architecture, programming, cleancode, scs
Published: 2022-12-17 19:37:01

<small>Cover attribution: <a href="https://unsplash.com/@namroud?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Namroud Gorguis</a> en <a href="https://unsplash.com/es/s/fotos/computer-cassette?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a><small>
  

Programming techniques and languages have evolved to make reading more intuitive for people, moving from a more **#imperative** approach, focused on **how the task is processed**, to a more **#declarative** one, focused on **what is being processed**.

**This evolution is constantly changing** and, therefore, it happens that what 20 years ago was considered declarative today is likely to fall more in the category of imperative.

In this article you can see two examples of this transformation. The first case starts from the **#assembly** language of a _CPU_ and the second case from the **#css** _markup language_.

---

## Evolution of general purpose languages

### The for loop

```kotlin
// for-loop.asm

// source:
// https://eclecticlight.co/2021/06/29/code-in-arm-assembly-conditional-loops/
//
// here an imperative example of a classic for-loop
// written in ARM assembler code

// and the maximum index in X4:
MOV X5, #1 // start index = 1
MOV X4, #5 // end index = 5
for_loop:
    // do_something
ADD X5, X5, #1 // increment the index by 1
CMP X5, X4 // check whether end index has been reached
B.LE for_loop // if index <= end index, loop back
// next code after loop
```

```C
/*
* for-loop.c
*
* here you can show the declarative version of previous 
* assembler example, nowadays this language C implementation
* is an imperative example:
*/
#include <stdio.h>

#define ARRAY_LENGTH(array_var) (sizeof(array_var) / sizeof((array_var)[0]))

void main(void)
{
    int number_collection[] = {1, 2, 3, 4, 5};
    size_t collection_length = ARRAY_LENGTH(number_collection);

    int index;

    for (index=0; index < collection_length; index++) {
        do_something_with_number(number_collection[index]);
    }
};
```

```javascript
// for-loop.js

// here a declarative modern functional version of a
// ECMAScript 6 loop

const miscCollection = [1, 2, 3, "hello", "world"];

miscCollection.forEach((itemInCollection) => {
  doSomethingWith(itemInCollection);
});
```

---
## Evolution of CSS markup language

### The abstraction layer

```css
/*
* auto-layout.css
*
* Auto layout, imperative legacy css
*/

.horizontal-center-center {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}

.horizontal-right-center {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  align-items: center;
}

.vertical-bottom-center {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
}
```

```scss
/*
* auto-layout.scss
*
* Auto layout, more declarative version because of
* use of semantic scss mixins
*/

@mixin auto-layout-base {
  display: flex;
}

@mixin auto-layout-horizontal {
  @include auto-layout-base;
  flex-direction: row;
}

@mixin auto-layout-vertical {
  @include auto-layout-base;
  flex-direction: column;
}

.horizontal-center-center {
  @include auto-layout-horizontal;
  justify-content: center;
  align-items: center;
}

.horizontal-right-center {
  @include auto-layout-horizontal;
  justify-content: flex-end;
  align-items: center;
}

.vertical-bottom-center {
  @include auto-layout-vertical;
  justify-content: flex-end;
  align-items: center;
}
```

```typescript
/*
* auto-layout.css.ts
*
* full semantic vanilla-extract version
* https://vanilla-extract.style/
*/

import { mixVariants } from "@Utils/styles/mix-variants.css";
import { StyleRule, styleVariants } from "@vanilla-extract/css";

const base: StyleRule = {
  display: "flex",
};

const horizontal: StyleRule = {
  ...base,
  flexDirection: "row",
};

const vertical: StyleRule = {
  ...base,
  flexDirection: "column",
};

const horizontalVariants = styleVariants({
  center: [
    horizontal,
    {
      justifyContent: "center",
    },
  ],
  right: [
    horizontal,
    {
      justifyContent: "flex-end",
    },
  ],
});

const horizontalAlignVariants = styleVariants({
  center: {
    alignItems: "center",
  },
});

const verticalVariants = styleVariants({
  bottom: [
    vertical,
    {
      justifyContent: "flex-end",
    },
  ],
});

const verticalAlignVariants = styleVariants({
  center: {
    alignItems: "center",
  },
});

export const autoLayout = {
  horizontal: {
    center: mixVariants(
      horizontalVariants.center,
      horizontalAlignVariants
    ),
    right: mixVariants(
      horizontalVariants.right,
      horizontalAlignVariants
    ),
  },
  vertical: {
    bottom: mixVariants(
      verticalVariants.bottom,
      verticalAlignVariants
    ),
  },
};
```

---


```typescript
// AutoLayoutDemo.jsx
//
// This auto layout demo show examples of how to
// consume all above different style types
import legacyStyles from "./auto-layout-legacy.css";
import scssStyles from "./auto-layout.scss";
import { autoLayout } from "./auto-layout.css";

export const AutoLayoutDemo = ({ ...other }) => {
  return (
    <article>
      <section class={legacyStyles["horizontal-center-center"]}>
        <p>Horizontal Center Center</p>
      </section>

      <section class={scssStyles["horizontal-right-center"]}>
        <p>Horizontal Right Center</p>
      </section>

      {/* 
        finally, the bellow example use the vanilla-extract
        compiled css resources. Vanilla-extract is not a 
        runtime performance penalty tool like styled-components
        or other similar inline styles tools
       */}
      <section class={autoLayout.vertical.bottom.center}>
        <p>Vertical Bottom Center</p>
      </section>
    </article>
  );
};
```

---


Thank you for taking the time to read and share your thoughts.

<div class="badge-base LI-profile-badge" data-locale="es_ES" data-size="medium" data-theme="dark" data-type="VERTICAL" data-vanity="julianmulet" data-version="v1"><a class="badge-base__link LI-simple-link" href="https://es.linkedin.com/in/julianmulet?trk=profile-badge">Julián Mulet</a></div>