The Duck Tales
Tags: javascript, webdev, xstate
Published: 2020-02-19 05:31:55

---
title: The Duck Tales
published: true
description: A story about different point of view. And a Duck.
tags: javascript, webdev, xstate
cover_image: https://thepracticaldev.s3.amazonaws.com/i/gb250lcaoohtcbrncdmn.png
series: Do not just code
---
> Once upon a time I was thinking about all the stupid things and other shenanigans I've done throughout my life. Things, I never wanted to create, things I never wanted to rewrite, and things I wanted to never see again. About thoughtfulness and a bit of wisdom. 

4 things to keep in mind:
- 🦆: If it walks like a duck and it quacks like a duck, then it must be a ~~duck~~ JavaScript [Duck-Typing](https://en.wikipedia.org/wiki/Duck_typing).
- 🙈🙉: Our world is experienced differently by blind or deaf people, but it's still the same world, just different perspectives - [6 vs 9](https://www.google.com/search?q=6+vs+9), as well as [blind men and an elephant](https://en.wikipedia.org/wiki/Blind_men_and_an_elephant)
- 👁: An observable system is one whose __internal state can be deeply understood__ just by observing its outputs.
- 🔨: __if all you have is a hammer, everything looks like a nail__ - [Law of the instrument](https://en.wikipedia.org/wiki/Law_of_the_instrument) 

> Which was originally known as _"Give a boy a hammer and chisel; show him how to use them; at once he begins to hack the doorposts, to take off the corners of shutter and window frames, until you teach him a better use for them, and how to 👉keep his activity within bounds👈."_

And I am going to give you a really BIG HAMMER. Believe me or not, you can use it to _hammer_ literally any problem.

***

- church bells ringing.
- the appearance of a man in a tuxedo with a woman in a flowing white gown.
- rice flying through the air.

🙀 sounds like a wedding! // The theory behind [Complex event processing](https://en.wikipedia.org/wiki/Complex_event_processing).

***

There is a little problem with React and Redux state. And the idea of `State` in general - it's not necessarily a state, that's just a collection of some values - a few `key`/`value` pairs just met in one place and formed some `data`. Dead data. Impossible data.

Confused? Well, "confused" is your `state`. My words have changed something inside you, and the result can be observed as a final emotional state on your face – 😕

> But - if you _walks like a `confused` and you quacks like a `confused`, then you are a `confused`_. And everything else is implementation details 😟

That is a core idea of [Duck Typing](https://en.wikipedia.org/wiki/Duck_typing) and this idea will save your life. Already saved, maybe even multiple times, because _Ducking_ – is what doctors do. 

It's called a `triage` – an attempt to understand the patient's state, the major problems and the minor problems, to save their lives. Just by looking at them, looking at how they walk and how they quack. Hopefully just looking first, and using surgery to get guts out only if necessary.

> Triage is the process of determining the priority of patients' treatments based on the severity of their condition - [Wikipedia](https://en.wikipedia.org/wiki/Triage)

In short, when a patient comes – nurse checks: 
1) the patient is yet alive
2) is not actively dying
3) and has a medical insurance
No insurance? Then the patient is probably healthy.

> If it walks like a 🤒, and quacks like a 🤧 – it's 😷! Cut a leg!

Just remember the last time you went to the GP - they asked you some questions, measured your temperature and pressure, and came up with some conclusion about your health problem - like `drink more water`. Next!

Usually, there are enough indicators to __intent__ the overall system state - is it actually in a "healthy" state(it does not matter how exactly) or it's in an "unhealthy" state(does not matter how exactly).

> The goal of triage is not to heal💉, but plan the next step.

Signs, Signs are everywhere! Just read them! And dont forget to left the breadcrumbs, that’s called a good UX. And _rice flying through the air_.


![Signs are everywhere](https://thepracticaldev.s3.amazonaws.com/i/8niazt5qrrheghyvqux3.jpg)


In the same way doctors are able to understand what’s wrong with you JavaScript is able to understand why _undefined is not a function_. Well, what is a function? What is an object? What is an array?

> if something has `.push` and `.forEach` - then it could be an `Array`. Or, at least, something `Iteratable`. 👉 it doesn't have to be an `Array` - it should 🦆 as `Array`.

But there is one moment - a thing could contain many different properties, implementing different interfaces, like `IDuck`, `IQuacker` as well as `IEggLayer`, and duck like a `pack`.
This makes things a bit complicated... to explain...

# What I am looking for?
I personally prefer to call a principle behind this question a __WTF principle__ - like you are displaying your cool stuff to a friend, manager, investor or QA engineer, and they are asking you: "_So, ok that was cool, but could you please explain 👉WTF is this👈?".

> Belive the old pirate - this is exactly how all your friends are thinking about your new creation.

You may replay in a short and sound manner - 🤬, but you know, there should be a better way to answer, and a bit more polite. 
And probably your friend, manager, investor or QA/QE need different responses.

It's actually very hard to predict what these different people might __want__ to hear from you, it's better and much easier to understand what they __need__ to hear. To do this let's just imagine that they are in the same situation as you, and would have to talk about "your stuff" with someone else. Then - let's go and find the top of this food chain:

- 💰CEO: Hey, I need you to build a new feature. I don't care how you will do it, I just trust you.
- 😎Director: Hey, I need you to build a new feature. I don't care how you will do it, I just trust you.
- 😸Manager: Hey, We need you to build a new feature. I don't care how you will do it, I just trust you.
- 👻Quality: Hey, I do care how you will do, not what. And I just don't trust you.
- 🤖Developer: 👉Hey, I've built a cool stuff👈

There is an expectation of Trust going from the top to the bottom, and no one is actually interested in the implementation details... so...

So the expectations for the `backflow` are the same - something they can __trust__, and nobody interested how you actually did it - that's implementation details, not the product itself. And you were asked to create a product 😉.

And "trust" means - your work shall __meet some expectations__, probably unique for every level.

> If it walks like our `acceptance criteria`, and quacks like `what we asked for` – it's our `feature`! 🚀Ship it immediately🚀!

This is something you shall keep in mind -

{% link thekashey/prefer-integration-tests-think-twice-1l6d %}

# Duck typing
As I said above - a single thing could quack like a __pack of ducks__. Let's ask every 🦆 in that pack, how it _quacks_ about a `Good Product`:
- 💰bussiness: It should be profitable. ~~My~~ Your salary depends on it.
- 🤖developer: It should be maintainable.
- 🚀performance: Loading time can't be more than 2 seconds.
- 🕸network: latency below 300ms.
- 🕵️‍♀️QA: code coverage above 95%.
- 👩‍🎤design: all margins should be the same.
- 🚔GDPR: Ha-ha! Gotcha!
- 👂a11y: don't forget about us
- 🤖another developer: And it still should be fun!
- 🕵️‍♀️QA: me again. Here are 20 __testing notes__ you should check your PR against, which is basically everything above. You're welcome, enjoy your day.

> Yep, QA/QEs are duck typing their expectation since forever.

Long story short - if `Product` wants to be a `Good Product` it should meet different and __parallel__ expectations. For every case, there should be a simple `acceptance criteria`, and it should be clear how to meet these requirements. 
One by one.

***

To better understand this moment, let's take a step back, and refer to the ancient knowledge. To the [Blind men and an elephant](https://en.wikipedia.org/wiki/Blind_men_and_an_elephant)

![Blind Monks and an Elephant](https://dev-to-uploads.s3.amazonaws.com/i/nzv5asba07hmlwkzdiy6.jpg)

> A group of blind men heard that a strange animal, called an elephant, had been brought to the town, but none of them were aware of its shape and form. Out of curiosity, they said: "We must inspect and know it by touch, of which we are capable". So, they sought it out, and when they found it they groped about it. 
- In the case of the first person, whose hand landed on the trunk, said "This being is like a thick snake". 
- For another one whose hand reached its ear, it seemed like a kind of fan. 
- As for another person, whose hand was upon its leg, said, the elephant is a pillar like a tree-trunk. 
- The blind man who placed his hand upon its side said the elephant, "is a wall". 
- Another who felt its tail, described it as a rope. 
- The last felt its tusk, stating the elephant is that which is hard, smooth and like a spear.

In some versions, the blind men then discover their disagreements, suspect the others to be not telling the truth and come to blows. 
In some versions, they stop arguing, start listening and collaborate to "see" the full elephant.
In another, a sighted man enters the parable and describes the entire elephant from various perspectives, the blind men then learn that they were all partially correct and partially wrong.

👉 🦆 are the blind men and your application is an Elephant 👈

You might try to describe it in various ways, and then find a whole object, matching all expectations at once.

***

In big companies, there are different _ceremonies_, _patterns_, _protocols_ and _standards_ you have to meet to launch a new product. You have to pass audits and reviews, but that is... __so boring__.

There should be a better way to understand what shall be done, and thus let's recall another piece of ancient knowledge, recall what a _classic_ said (Lev Tolstoy, 1828): 

> All happy families __resemble each other__, 
each unhappy family is unhappy in its own way.

In other words: happy families __share a common set of attributes__ which lead to happiness, while any of a variety of attributes can cause an unhappy family. 

This concept, known as [Anna Karenina principle](https://en.wikipedia.org/wiki/Anna_Karenina_principle), is quite fundamental and explain a lot - from animal domestication to PayPal (🤷‍♂️ according to Wikipedia)

And you know - All happy families resemble each other, as well as All __Little Black Rain Clouds__ resemble each other. There is no difference.
They are all black, rainy, and not as small as that bear. Oh, that's a bear!!!

![Pooh the Little Black Rain Cloud](https://thepracticaldev.s3.amazonaws.com/i/536se7jdb5sj3sdfu1rl.png)

And again, it's a subtype of Duck Typing.

> We will return to the `little`+`black`+`rain`+`clouds` later, as well as check why the `green great dragon` cannot exist...

# Behaviour
Let's try to formalize Duck Typing for some Application. Should be pretty straightforward (if not - we are doing something wrong):

- Let's imagine you are a QE, and I am demoing my stuff to you
- Then, when I press that button
- Something magical should happen (and not an explosion)

Not quite formal? What about this:

```
Given: "localhost:8080/my-cool-app"
opened in a Google Chrome

When: I press the Big Blue Button

Then: "Hello World" is displayed
```


That might look like [BDD testing](https://en.wikipedia.org/wiki/Behavior-driven_development), with all those `Given/When/Then`, but it's actually Duck Typing, again and again.

```
Given: a 🦆
When: you kick the 🦆
Then: it quacks
So: 🦆 is alive
```

This principle also is known as [smoke tests](https://en.wikipedia.org/wiki/Smoke_testing_(software))

>  an acceptance test is preliminary testing to reveal simple failures severe enough to, for example, reject a prospective software release. Smoke tests are a subset of test cases that cover the most important functionality of a component or system.

## Let's write a bit more tests
What would you say about this one?

```
Given: a 🥛 glass of water
Then: it's full
When: you take a sip
Then: it's 70% full

When: you take a sip
Then: it's 40% full

When: you take a sip
Then: 🥛 glass is empty
```

Probably there are some implementation details. Like 30/30/40 per cent of the water sipped every time. That's too fragile

```
Given: a 🥛 full glass of water
When: you take 3 sips
Then: 🥛 glass is empty
```
Much more compact, and sound.

## 6 vs 9 ?
`6/9` is about different perspectives. Like the 🥛glass could be 50% full as well as 50% empty.
What if the same actions affect more that one thing?

```
Given: you are thirsty 
When: you take 3 sips
Then: you are full
```

Of course! You action affects not only a 🥛glass, but you as well.
Another example? The opposite this time.

```
Given: 🌏 is spinning
When: you take 3 sips
Then: 🌏 is still spinning
```

__All our tests__ are the same:

#### Given
- you open some `Page`, or mount some `Component`
- you provide some `data`, or some `props`

#### When
- you click somewhere
- you change some props or data
- you perform some action

#### Then
- you again check something
- you expect to be "somewhere"

```text
 Given 👉 When 👉 Then
```

{% twitter 1219963656089341952 %}

What it actually IS? Remove all sugar, remove all extra words. What is THE MAIN?

> Given -> When -> Then

> Precondition -> Action -> Postcondition

> Somewhere -> Action -> Somewhere else

`Where we are` -> `What we do` -> `Where we are`

----

Long story short - this is how `State Machines` works. All those BDD tests are testing nothing more but `transitions` from one State to another State, caused by some event. Nothing more.
> Or from some `data` to some `data`, like in __Redux__/__Flux__

State + Action = New State

![state](https://thepracticaldev.s3.amazonaws.com/i/gj2v9hcu624t63uvsvex.png)

This image is taken from @davidkpiano presentation [Infinitely Better UIs with Finite Automata](https://slides.com/davidkhourshid/finite-state-machines#/16), and there is also a few xstate-related articles you can read at dev.to (and much more in the wild).

{% link davidkpiano/no-disabling-a-button-is-not-app-logic-598i %}

## Quack!

However, you know, state machines are great... but while we are talking about them, you probably do not use them in your code.
However, I would not be so sure, even if you really don't use them intentionally, explicitly or even implicitly.

Finite State Machines are all about the finite amount of States something could be in, and by some reason. Like could be little black cloud not rainy? Could large rainy cloud not black? What is your expectations from the cloud? Why do you think it is rainy?

Even if David once said - _"disabling a button is not app logic"_ - "Disabled Button" has to have `disabled` attribute, or at least looks like disabled. Well, quacks 🦆 like a `disabled`, so everyone will understand your intent. `WAI-ARIA` included.

> 👁: An observable system is one whose __internal state can be deeply undertood__ just by observing its outputs.

So, keeping the main principles of Duck Typing - is it possible to __infer the Page State from observing the Page__?

> What if we know how every page __state should quack__. Could we __find the right duck__?

-----

🦆 + action = 🦆

-----

However, is it really the case? Let's recall the case with a cup of water.

```
Given: you are thirsty 
When: you take 3 sips
Then: you are full
```
You were in one 🦆, took an action, and now you are in another 🦆. In reality you just drunk some water, and your digestion system reported that your are now ok. In fact you are not yet, the water is yet in your digestion system. 
👉 The BDD test is actually testing a __derived__ reaction. Which is even not real.

It tests the RESULT, not the implementation details. You heard it multiple times, and let's recall another ancient knowledge to understand the meaning.

***

```
Life is a journey, not the destination.
```

Well in our case it’s the opposite. The destination is the reality, and the journey is an implementation detail.

> To finish the moment, to find the journey’s end in every step of the road, to live the greatest number of good hours, is wisdom.

***

[Allegory of the cave](https://en.wikipedia.org/wiki/Allegory_of_the_cave), Plato's, 514ad. Which is, long story short, "The Matrix".

> Plato begins by having Socrates ask Glaucon to imagine a cave where people have been imprisoned from childhood. These prisoners are chained so that their legs and necks are fixed, forcing them to gaze at the wall in front of them and not look around at the cave, each other, or themselves. 
Behind the prisoners is a fire, and between the fire and the prisoners is a raised walkway with a low wall, behind which people walk carrying objects or puppets "of men and other living things". 
The people walk behind the wall so their bodies do not cast shadows for the prisoners to see, but the objects they carry do. 
The prisoners cannot see any of what is happening behind them, they are only able to see the shadows cast upon the cave wall in front of them. The sounds of the people talking echo off the walls, and the prisoners believe these sounds come from the shadows.
👉 The shadows are reality for the prisoners because they have never seen anything else; they do not realize that what they see are shadows of objects in front of a fire

![shadows on the wall](https://dev-to-uploads.s3.amazonaws.com/i/pn09xg42jwgflx5bjquy.png)

By now you should understand, that your code, your codestyle, patterns and everything else are "the real objects", but "the prisoners", your users in this case, are able to see only _shadows_.

Real customers are facing the combination of many unrelated to each other processes, TCP/IP and the way their screens displays the data included.

> 😉 if it walks like an Application, and it swims like an Application, that's an application, not a random collection of bytes.

***

## Reverse Duck

Reverse Duck is what our E2E tests (should) look like 
– open some page, and assert some selector. If that selector exists – then we are on the expected page, and the test continues.
- We are doing some actions, and again checking some selectors - is our page walks like the right page?
- doing more actions, and again checking selectors - is our page swims like the right page?
- Oh, it is not? quack!

Every test starts in one 🦆, and ends in another 🦆. Your ability to test your application is limited to your ability to define those distinct states, and here a picture, explaining a lot, again from one of David's presentation. [Write fewer tests](https://slides.com/davidkhourshid/mbt-cse#/14) this time.


![Automated tests](https://thepracticaldev.s3.amazonaws.com/i/drwe74xedrlkfjcbg9p7.png)
👉On the picture: you are in the State A, and you know "how" to go from it to State B or State C - you can create an automated test checking that your application is working "as designed".


> All good applications resemble correct ~~business processes~~ state machines behind.

Having your application described as a state machine you CAN try to move from one State to another State and assert the result. Like:
- have you reached the right State, as it was designed?  
- could go from the Very Beginning to the Very End?
- could you test transition between any sibling states?
- could you start your application in any Specific State? If not then why?
- could you understand that your application is in some Specific State right now?

Works in a quite obvious way - exactly as we need:
```
Given: 🦆 > ducks like your Home Page
When: You press The Most Important Button
Then: 🦆 > still ducks like your Home Page 😅
```

Unfortunately, not many application works that way, especially SPAs - usually, they are a bit more complex. Usually, our applications are `Big Machines`, composed of `Smaller machines` - 🦆🦆🦆🦆, the Pack of Ducks.

If you just clicked `The Most Important Button` - it might open a `Modal Dialog` - like it added something on the page, something parallel to everything else. A new 🦆.

```
Given: 🦆 > ducks like your Home Page
When: You press The Most Important Button
Then: 🦆 > still ducks like your Home Page, 
         > and The Modal Dialog
         > and network activity indicator
         > and system await user action
         > ....
         > there are just not “blind monks” describing your Elephant
```

Good examples of "small machines", many of which could be found inside bigger ones are `React Hooks` - __small and simple__ state machines. And they can form __React Component__ - a `Big Machine`, the composition of some data machines (`useState`) plus effect machines (`useEffect`).

There is no way you can reproduce a really Big Machine using one State, but who said it should be one?

- when you are opening your application – you are changing it State. From `Closed` to `Open`.
- when you changing а current page – you are changing a nested machine state or sub-state. From `Page A` to `Page B`.
- when you are changing something on a page, filling `inputs` in the `Form` you are not changing anything, except machines inside those inputs. 
- but once you have filled everything a `Form State` could change –  Empty->Invalid->Valid.
- there are many state machines coexisting in your application. Without proper management it is leading, I'm afraid, to [Schizophrenia](https://en.wikipedia.org/wiki/Schizophrenia)
- with proper management, they form [Akinator](https://en.akinator.com/), which is nothing more than a pretty big `decision tree`, which is, well, __Recursive Duck Typing__. And Triage.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/65t7ko46qgirnqhwb4cg.png)


To prevent any misunderstandings let's define terminology:
- `State` – is an internal state of an object, __not observable__ from outside. Like React or Redux state. It could be even NOT used for the current page (There is always some useless pieces of data 😿)
- `Duck State` – is a part of an underlying state machine, including the “shadow” of explicit machine __observable from outside__. And let's call it a `Phase`.

> `Phase` of a State Machines is the current `state` this machine is in. Like you are `reading article`. State machine might be in single one state at the one point of time, but remember 🦆🦆🦆 - there could be parallel and nested machines.

It's easy to distinguish State and Phase:
- State could be a composite object, with dozen variables inside.
- Phase always just one. The something major about the subject greatly altering subjects behaviour.

> think about the blind monk. The monk as to describe what he experienced in one or two words. Which?
If you are not able to do it - add more monks.

## Tier
You cannot represent😅 your application with a simple and only one state machine - the real application is like a puzzle, or even like a Quest.
- you are in point A
- you have to play a mini-game, like a boss fight, to move to point B
- you are in point B
- ...
- that minigame is an application inside an application - a nested submachine
- that forms multi-layered, multi-dimensional or multi-tiered architecture

Or a Timing/Flow/Sequence Diagram, which explains what is happening layer by layer.

![Timing Diagram](https://dev-to-uploads.s3.amazonaws.com/i/pxrutzeiqhoedng4fsj1.png)

[Multitier architecture](https://en.wikipedia.org/wiki/Multitier_architecture) is quite common and popular. Many patterns could be considered as multi-tiered - from microservices to MVC. 
Usually, the separation between tiers is "logical": Presentation layer, Service Layer, Business logic layer, Data access layer. This is how the majority understands it. Not me.
I don't like this sort of separation, as well as I hate "testing Pyramid" and the separation between unit/integration and E2E tests - it's not logical.

> Really, "the difference" between `unit` and `E2E` tests that the first usually runs on the "server", and the "second" in the Browser. It's a separation by the tool used to run your tests, not the tests. And that's a good example of abstraction leaking.

- the first tier is a feature definition. It defines how something should work. This is what you want to build, not how.
- the second tier is a testing layer. A duck machine, where you have to define how every particular state quacks. This is where `Design` and `Observability` met each other.
- the third tier is the implementation of a specific component. Of a Step. How a single Big Machine should work.


> - is the current duck walking as expected, is current duck quacking as expected. 
- If no duck is quacking – it's a fail. 
- If more than one duck is failing – it's a fail.

Surprisingly – the last tier is helping to re-define the first. No Phases should quack the same. If something is different inside – it should be different outside.
Situations when customer trying to click a `save button`, without any effect cos it's "disabled", but not from UI perspective – much be not possible. 

> If this is a major `behavioural condition` – it shall have its own Phase, own State, and shall have its own Duck🦆.


By fact - is very hard to define the proper requirements, it’s really easy to desire something not you really want.
Like “build it with React and Redux” cannot be a business requirement, and usability, conversion rate and a11y cannot be a technical one.

***

Let’s refer to another ancient knowledge - the Djinn in the bottle.

- 🧞‍♂️: here I stand, let’s make it fast - 3 wishes
- 🙀: I want to be riiiich!
- 🧞‍♀️: as you wish, 😈

A moment later you are rich. Very rich. And old. And everybody hates you. And trying to kill you.  Cos you are Narcos.
Not actually what you wanted, but exactly what you’ve asked for.

> Just for your information - there is a film about it - [Bedazzled](https://en.wikipedia.org/wiki/Bedazzled_(2000_film)).

![Bedazzled narcos](https://dev-to-uploads.s3.amazonaws.com/i/1pwe6mew037skc82k01k.jpg)
> As a test, Elliot wishes for a Big Mac and a large Coke. The Devil takes him to McDonald's and places the order. Elliot has to pay for it, because, "there ain't no such thing as a free lunch." After taking Elliot to her office, based at a nightclub in Oakland, the Devil convinces Elliot to sign her contract, and delivers further wishes. Each wish has Elliot living them out with Alison and his co-workers in surrogate roles. However, the Devil always spoils his wishes by adding something he does not expect or want.


And, to be honest, that `evil djinn`, who is going to use everything you said against `you`... is `you`, who is doing exactly what was asked for, but... the devil is in details. And that `you` is `your project manager`.

Well, manager, you’ve got what you deserved. Next time be more precise, wish something you really need.

> It's always about your Duck definition. How it quack, what you asked Djinn for, what is the story of the blind man.

# Conclusion

The Duck Typing is a pattern matching. Is a way to define what something is by observing it.
It is a way to understand​ what something actually is.
It is a requirement to left some breadcrumbs, some details and nuances​ to be able to distinguish​ one duck from another.
It is how to stop being an evil djinn.
About what does really matters, and what is not.
It's about design, UX, monitoring and observability. As I've said in the beginning - you can hammer literally​ everything with it.

The `mental models` derived from duck typing might help you develop a more thoughtful​ solution, which would do what you really need, as well as define and clarify why you actually need.

Next time you will be asked​ to do something, just quack.

> PS: and here are the slides from the talk

{% slideshare pe6rGmEEykcQQT %}

{% youtube QrOUndxFmdA %}