Vantage Point - Combining the imperative and the declerative
Tags: javascript, es6, es2018, proxy
Published: 2023-10-20 15:30:15

---
title: Vantage Point - Combining the imperative and the declerative
published: true
description: Proxies are awesome
tags: JavaScript, ES6, ES2018, Proxy
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dy7iibn2w5jlmb4dkhbr.png
# Use a ratio of 100:42 for best results.
# published_at: 2023-10-19 23:25 +0000
---

![vantage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dy7iibn2w5jlmb4dkhbr.png)

I always take the new shiny bits from TC39 with a pinch of salt. I have been honest about some of the [additions to the language](https://medium.com/@ibowankenobi/the-amazing-yield-b49710207703) before, but this will be a good one. 

For me it has always been a pain, not to be able to respond to arbitrary property accesses without some safety net. Whether we are talking about a `Class` or an `Object`, your options were:
- hardcode the property from an `array-like` using `[[Set]]` or `defineProperties`
- dodge the error using optional chaining or nullish coalescence
- create a method on the prototype chain that accepts an arbitrary string, corresponding to the property to be accessed.

None of the above feels natural, aka, you cannot do: `someObj.someArbitraryString` and return something other than `undefined`. For that reason `Proxy` was a great addition to the language simply because a polyfill was not possible.

Proxies empowered ALL of the objects in JS. Not just Arrays, Objects, Maps etc, but functions too. I want to talk about the function part, because a pattern that I unconsciously started using for over a year kept coming back and proved to be extremely useful. It stayed on the shelf for some time while I used it, and now I have at least something little to show.

Consider this:
```js
ch.li /* returns a li DOM object */
ch.div /* returns a div DOM object */
```
One would think it is some sort of a class or object that has a method, no it is not:

```js
ch.whatever /* <whatever></whatever> */
ch(ch.whatever).set("innerHTML", "what?") /* <whatever>what?</whatever> */
```
taking it a step further:

```js
ch(ch.li)`
sappend ${ch.span}
set innerHTML ${"what?"}
style ${[["width","40dvw"],["height", "auto"]]}
`
```
Above 'sappend' is short for 'select and then append'. A bit more with shortcuts to commands:

```js
ch(ch.li)`
+-> ${ch.span}
>> innerHTML ${"what?"}
style ${[["width","40dvw"],["height", "auto"]]}
`
```
and why not alternate between template literals and classic function calls:

```js
ch(ch.li)`
+-> ${ch.span}
>> innerHTML ${"what?"}`
.style([["width","40dvw"],["height", "auto"]])
.select(ch.div)...
```

or maybe this is better?:

```js
ch.dom`
    <li>
        <span style="width: 40dvw;">what?</span>
    </li>
`
```

what about children?:

```js
ch.dom`
    <li>
        ${Array(10).fill().map(d => `<span style="width: 40dvw;">what?</span>`)}
    </li>
`
```

wait a second, what if:

```js
ch[`li{"attr":[["data-name", "I am a li"]]}`]
```
styles, attributes may work like above, what about props??

```js
ch[`li{
"attr": [["data-name", "I am a li"]],
"prop": [["a",${3}], ["b", ${4}]]
}`]
```
does it mean you could do?:

```js
ch[`li{
"attr": [["data-name", "I am a li"]],
"prop": [["innerHTML", "what?"]]
}`]
```
can we combine them all?:

```js
ch(ch[`li{
"attr": [["data-name", "I am a li"]],
"prop": [["innerHTML", "what?"]]
}`])`
    +> ${Array(5).fill().map((d,i) => {
        return ch.dom`
            <span>
                <i>HELLO!</i>
            </span>
        `
    })}
`.selected //logs the li element
```

Marking a `parentNode` or any other variable to do something with it later:

```js
ch`
-> myLi:${
    ch[`li{
        "attr": [["data-name", "I am a li"]],
        "prop": [["innerHTML", "what?"]]
    }`]
}
+> ${Array(5).fill().map((d,i) => {
    return ch(ch.dom`
        <span>
            <i>HELLO!</i>
        </span>
    `).on("pointerover@mynamespace", () => console.log("mouseover!")).selected
})}
=> ${({values}) => () => console.log(values.myLi)}
`
```

And if you were to call function parameters inside a tagged template literal, you would need spreading. Sure, why not?:

```js
ch`
-> ${ch.li}
on ...${["click@someNameSpace", (e) => {console.log(e.clientX)}]}
+< ${document.body}
`
```

Here we created a `li` element, added a `click` event listener on it with `someNameSpace` (so that we can later remove all the listeners registered with that namespace) and appended that to the `body`. The event and the handler is passed in an array inside a template literal which is spread to `on` function.

In none of the examples there is a `build` step involved. It all is based on about 160 lines of ES6 - ES2018 JavaScript. Here is a [codepen ](https://codepen.io/IbrahimTanyalcin/pen/BaMBOzY) with some of the examples above.

At this point you might ask what a TODO list would look like, there you go:

[![TODO](https://cdn.jsdelivr.net/npm/cahir@0.0.2/static/img/cahir_todo.png)](https://codepen.io/IbrahimTanyalcin/pen/ExrYZZG)

Many of you are using frameworks, I won't be giving names here, and it is totally perfect when it comes to getting the job done. Programming is somewhat bit of an art when compared to positive sciences like physics and math, and for that reason, there is more than one optimal way of doing things, I definitely cherish the differences. Also different stacks for rendering the same "Hello World!" page has packed a lot of documentation through the years, so it is not possible for an average person like me to know everything.

Here is the thing, the examples you saw in this article are `imperative` compared to `declarative`. Due its nature, imperative programming has been a bit more verbose because the programmer has to instruct the `how to` rather than `what to`. But in the face of ES6+, it does not have to be like that anymore. I hope I could prove a point.

Why is the above important? Because `imperative` represents control and `declarative` represents abstraction. You want to abstract because you want to avoid the pain and make it easier. You want imperative because you want to specifically control the flow of your functions to create the exact effect desired. Both can be combined.  

Using this small library, I was able to create complex data visualizations, interfaces using simple routines and web components. When it came to fine tuning and controlling rendering cycle, I was able to control the DOM operations because the setup is imperative by nature with declarative bits.

Complex visualizations or interfaces go through a process called `Enter - update - exit` cycle. Which is reminiscent of how D3 works, and most of the frameworks today use that logic behind the scenes by specifying a `key` value to decide with nodes to add/remove/change. This also can be done, [here is a static example I put together](https://ibrahimtanyalcin.github.io/Cahir/). You can pause and call Array methods on the `data` in the inspector. See for yourself. 

There is a lot of work to do. The [helper methods](https://github.com/IbrahimTanyalcin/Cahir/blob/master/collections/DOM/ch.js) that are mounted on the `Proxy` needs documentation in JSDoc. If you are interested, here is the repository:

[**Cahir**](https://github.com/IbrahimTanyalcin/Cahir)

Almost a decade and half of developing open source/proprietary visualizations in bioinformatics has thought me that `what works` >>> `what is trendy`. I understand people refraining from taking risks of dunking into works of others and instead going for the safe route of `frameworks` because "they know better than you do." There is also a large cohort of young people who desperately need a paycheck and have no option other than investing into whichever soup of the day stack that lands a job in this VC poisoned market. 

I get all of the above. I also get the idea of `standing in the shoulder of giants`. We all, whether we want or not, stand in one way or another in the shoulder of a giant. I believe the key is to find a balance, and sometimes try to ask the question "what if". I think the only sustainable leverage is a vantage point, a vantage point that can incorporate the old and the new, that can keep what works and discards what doesn't.

If you like the [repository](https://github.com/IbrahimTanyalcin/Cahir), please try to help me to make it better by submitting PRs and documentation suggestions. If you like it, a star would not hurt.

Have a great weekend,