joicomponents
Version:
Design patterns to build native web components
176 lines (152 loc) • 10.6 kB
Markdown
# What is beauty?
## Discussion: Can code be ugly and pretty at the same time?
This is an intriguing question. But, its answer rests on answers on some other fundamental questions.
What is ugly and pretty code? Why can I feel code as either ugly and/or pretty?
And what does it all mean?
Ok, the last question. That might be a bit of a stretch. And we know the answer already: 42.
But the other questions, what has computer code to do with esthetics?
Why do I "sense" code as being "ugly" or "nice"? Why's that?
To me, code can be pretty when:
* its structure is clear and clarifying,
* it me shows both a problem and a solution I had not seen before, but still recognize,
* it solves a familiar problem in an unfamiliar way,
* or an unfamiliar problem using a concept I already know,
* it teaches me something new, makes a structure or grammatical form or a metaphor familiar,
* it fits my peculiar stylistic choices, like not using braces in single line if clauses and
functions with inverse if-clauses that exits a function instead of wrapping blocks
into blocks into blocks, because that is the way I like it.
* nicely modulated, ohh, that is important, well formed functions and modules and interfaces,
* aligns nicely in my current editor,
* etc. etc.
Code is ugly when it is:
* boastful, but without merit,
* adds complexity unnecessary,
* obfuscates for reason,
* verbose,
* unfamiliar,
* uses wrong API functions or strategies that might become a problem later,
when the platform or use-case slightly changes,
* it is not mine, and I don't want to add the complexity nor responsibility of others code,
* it is from an institution or person I don't trust, and I'm not in a trusting mood.
* etc. etc.
My esthetic sense for code is not rational.
Pretty and ugly is not computed by a single threaded rational, consciousness.
Rather, it is based on my feelings and my mood at that moment. My subconsciousness.
My feelings towards a piece of code is based on my personal experience and my style.
It is directed towards my current needs and trends I like.
It is multithreaded. It is analogue.
It is not linear, it can change dramatically with just a slight adjustment in one of its input parameters.
And I trust it. Partially. As I would trust any other gut feeling.
I believe that ugly code will just give me problems and pain.
And cause all other people in the world problems and pain, that is when I don't get over myself
and have forgotten that a) we are all different and b) that is ok.
I feel that pretty code will somehow give me pleasure and sweetness.
And I so hope that others will feel the same about my code.
And I feel at home and with friends when they do.
In my single threaded consciousness I have rationalized that my code instincts has a purpose.
That my sense of beauty and ugliness is given to me by evolution.
My esthetic sense is my minds GPU.
It has been developed to recognize landscapes in which fruits and prey likely would occur.
Landscapes where I might find shelter, from beasts and from the elements.
It has been developed to let my prior experiences to mix together with the teachings of others
that I to some degree trust.
If I had seen snakes behind stones that looked like those stones over there,
those stones over there would echo the ugly face and venom of that last snake.
The stones might also remind me of something that my stupid, untrustworthy uncle like so much.
It all blends together to immediately give me a sense of what to do.
And for me this is the key to understanding that first question.
Can something be beautiful and ugly at the same time?
The answer is yes. Looking at a landscape can give me associations of *both* berries and snakes.
It needs a closer look. Where might the snakes be? And where can I find those berries?
And they might be inseparable. The snake is likely coiled up right under the berry bush so
as to strike out at the next frightened, but hungry mouse that come looking for some sugar.
Code is the same. Sometimes, if you build your bush of berries in a place where
the snake can't hide in it, all the berries will just be eaten by mice, after some months.
On some rare occasions, due to the environment, to keep the sweetness you must include ugly.
You must write some code that immediately strike you and others as ugly and wrong, but
that your gut tells you will be the right choice when you need it later.
Or at least the best of currently available alternatives.
And so it is with the punchlines of `setupCallback()`.
Delaying `setupCallback()` in a mixin, might make it look prettier at first.
But the mice that hide in the mixins will eat the berries of `setupCallback()`
as soon as you turn your back to them. I can feel it.
I feel that this mixin will be combined with another mixin that a) will run some code it shouldn't
*before* `setupCallback()` is invoked or b) for some reason should not(!) be delayed in such a manner.
And I feel that when using a mixin, you will discover this problem too late,
after the harm is done and these mixin mice has eaten all the setup berries.
The punchline snake however will stay where you left it, right there at the surface.
That snake is ugly. Dangerous. But. The way it stays put and both guards the berries and keeps us
on our toes just the right amount, now that is beautiful.
Given a choice, the punchline snake is the one you want for `setupCallback()`.
Looking even deeper at the code, `setupCallback()` is just `constructor2()`. With makeup on.
Right now, it is actually hard for me to even imagine an uglier name for a method than `constructor2()`.
But what the hell. In the bar that is the `HTMLElement`, ugly is the norm.
And so if it is pretty with make up on,
one should accept that as the lesser of two evils.
Hey! Miss `Polymer.ready`, miss `DOMContentLoaded` or mrs `onlyOnceInConnectedCallback()` are
also just `constructor2()`, just with more/different makeup.
In this bar, less makeup is more beautiful.
You might still find the `setupCallback()` punchlines hideous.
They might scare you, and based on your experience and taste and sense of code,
you might choose to plant your bush of setup berries somewhere else.
I respect that. Although with a little resentment, as this is, after all, esthetics we are talking about.
I cannot help but feel that you will spread setup berries around the environment and
so contribute to spreading mixin mice or framework flees and other bad viral practices and trends
on our shared planet.
I, personally, will plant my setup berries next to the punchline snake.
I will spread punchline snakes.
I fear the mixin mice and frameworks flies more.
I know that dealt with correctly, the snake is less harmful to men than mice.
My last comment is this.
Bad code will steals time like nothing else.
It can break products and business processes worth millions upon millions.
To a business and job security, bad code is as dangerous as floods and hurricanes.
And it is the programmer that both accidentally makes it and tames it and defends it.
Code can frustrate you like nothing else.
And if you combine bad code with other people,
especially other people with no interest nor sense of responsibility for that code,
you are asking for trouble.
With experience, programmers will learn to associate the feeling of pain and frustration with certain type of code.
And they will learn to recognize sweetness and joy and flow and control in it.
A well developed sense of code is what separates the novice from the master, the good from the bad.
It is not smartness that will make you a good programmer.
To me, smartness is more likely to produce arrogant, brittle code, its beauty fading fast.
It is not primarily the ability to through concentration and extended memory
build and maintain large mental constructs.
Although useful, when such code needs to be updated, the programmer himself or others must do the same.
That is truly annoying, why couldn't that smartass have modularized his code a bit better in the first place?!
My point is this.
The sense of code that programmers develop is not quaint, not an irrelevant relic from the caveman.
It is not to be ignored. Rationalized away. Belittled. Dismissed as irrational. Viewed as unprofessional.
It is the most important part of the programmers mind, his most important tool*bag*.
It is why programmers are *humans*, and not machines.
## Opinion
However, could there be a world without snakes or mice or flies around the `HTMLElement` setup berries?
Yes, it could. I see only one problem that must be solved, and another potential that should be met.
First. Attributes from HTML template should be either:
1. set before the `constructor` of subclasses of `HTMLElement` is called, or
2. passed into this `HTMLElement.constructor` as arguments.
If the [Problem: no attributes in constructor](Problem1_attributesInConstructor.md) is solved,
the pressing need for a constructor2 would vanish.
Second. A set of universal HTML attributes that developers can flag elements with in HTML template to
1. *delay* calling the constructor of elements with such a flag,
2. including all their lightDOM children,
3. that lets these elements exist in the DOM as "delayed" elements,
4. until the premises behind that flag (or set of flags) get fulfilled, the flag(s) is removed and
the `constructor()` and `connectedCallback()` gets called.
Such flags are nothing new. They echo `defer` and `async` of for example `<script>` elements.
But they fit slightly different use-cases such as:
* "defer=idle": the element is constructed only when the browser has idle resources.
* "defer=inView": the element is constructed first when it enters the viewport.
* "defer=nextAnimationFrame": the element will be constructed in the next animation frame,
allowing other elements to be prioritized.
Another solution would be to consider such a flag a CSS property, akin to `display: none`.
However, this is an inferior solution. As this does not concern an elements style, look or feel per se,
and as this is state information that should update when the flag is removed automatically later.
It is not CSS.
The problem is that there is no way to delay the lightDOM child branches..
They will be connected to the DOM, even when they are not shown until later.
The best alternative therefore is simply to mark the element with display: none and remove that later.
That will at least give the browser a clear sign that these elements
*can be* prioritized below other template and code.
*If* the browsers do that, I don't know..