Post author here. I'm following the global #AWS outage. #HugOps to the people there, and everywhere restoring service.
Complexity is what it is...
However, I feel we as software people---executive, product, design, engineering, the whole nine yards---ought to think systematically in terms of Software Debt, as software organisations.
;; Clojure source code for `comp` (since Clojure v1.0)
(defn comp
"Takes a set of functions and returns a fn that is the composition
of those fns. The returned fn takes a variable number of args,
applies the rightmost of fns to the args, the next
fn (right-to-left) to the result, etc."
{:added "1.0"
:static true}
([] identity)
([f] f)
([f g]
(fn
([] (f (g)))
([x] (f (g x)))
([x y] (f (g x y)))
([x y z] (f (g x y z)))
([x y z & args] (f (apply g x y z args)))))
([f g & fs]
(reduce1 comp (list* f g fs))))
With telecom, we benefited from skipping generations. I got into a telecom management program because in 2001-ish, I was passed by on a village street by a farmer bicycling while talking on his cellphone. Mind you my family could not afford cellphone call rates at the time.
In fact, the technology was introduced out here assuming corporate / elite users. The market reality became such that telcos were forced kicking and screaming to open up networks to everybody. The Telecom Regulatory Authority of India (back then) mandated rural <> urban parity of sorts. This eventually forced telcos to share infrastructure costs (share towers etc.) The total call and data volumes are eye-watering, but low-yield (low ARPU). I could go on and on but it's just batshit crazy.
Now UPI has layered on top of that---once again, benefiting from Reserve Bank of India's mandate for zero-fee transactions, and participating via a formal data interchange protocol and format.
Speaking from India, having lived here all my life, and occasionally travelled abroad (USAmerica, S.E. Asia).
We, as a society and democracy, are also feeling the harsh, harsh hand of "Code is Law", and increasingly centralised control of communication utilities (which the telecoms are). The left hand of darkness comes with a lot of darkness, sadly.
Which brings me to the moniker of "third world".
This place is insane, my friend --- first, second, third, and fourth worlds all smashing into each others' faces all the time. In so many ways, we are more first world here than many western countries. I first visited USAmerica in 2015, and I could almost smell an empire in decline. Walking across twitter headquarters in downtown SF of all the places, avoiding needles and syringes strewn on the sidewalk, and avoiding the completely smashed guy just barely standing there, right there in the middle of it all.
That kind of extreme poverty juxtaposed to extreme wealth, and all of the social ills that come along with it, have always been a fixture of the American experience. I don’t think it’s a good barometer or whether the USA is in decline when there has long been pockets of urban decay, massive inequality, drug use etc. Jump back to any point in American history and you’ll find something similar if not much, much worse. Even in SF of all places, back in the wild west era gold rush or in the 1970s… America has always held that contradiction.
Yeah, I sort of recounted a stark memory. That juxtaposition was a bit too much.
However, it wasn't just that, and the feeling has only solidified in three further visits. It isn't rational, very much a nose thing, coming from an ordinary software programmer (definitely not an economist, sociologist, think tank).
I really tried hugo, but I gave up because of hugo's many annoyances --- breaking changes in versions a mere few months apart (why????), yet another arbitrary templating system, poor support for org-mode out of the box, lots of impedance mismatch with ox-hugo (a valiant effort), runs a local server for local development, injects javascript for live refresh, etc...
Don't get me wrong, it is a really nice project which I do recommend to people who don't want to go down the path of writing their own custom site maker... The single-binary formula allows hugo to offer a much better set of trade-offs than the competition.
But... if you can write your own, write your own. It is a glorious yak shave.
My only tip will be to avoid all dependencies like the plague. For stability and sanity.
The upshot... After over two years of using my dinky-ass handmade pandoc-usin' (not even parallelised) static site maker, I feel hugo is not even as fast as what I have.
Yeah, that's bitten me and it's super stupid. At this point, I've just pinned hugo so I don't update it any more. It's a friggin' static site with basically no Javascript (just a little for the site search feature—handled by the theme) so I don't feel any need to keep Hugo up-to-date.
First... Love your site (clean, fast, easy on the eyes, no need for JS to read). And your writing... yours is a proper blog. I used to feel bad about not being able to "just blog" like a real blogger, but I discovered that what I really like, is to write, in order to think. So, my blog has become part of my Big Reason to write (a lot) locally, and I am very happy to publish giant-ass blog posts; longform thinking.
Second... I went down a very similar path to custom site-buildin'.
Reject Wordpress because it's the 2020s -> reject anything mandating npm, gem, pip, lockfile web-scale dependency madness -> just hugo (single binary, wow) -> hugo + ox-hugo -> ouch, yet another custom templating language, and no backwards compatibility -> should I just Wordpress like it's 2005? -> NO, wait. Now I know programming. -> Voila! `shite` [1] (org-mode content -> pandoc -> plain HTML-and-CSS website [2]).
Third... Again... superfriend! 10000% same sentiment as yours:
> that takes exact same files and produces output that I fully understand e2e, becoming the project I'm most proud of
See my `shite`'s incredible documentation---animated GIFs and everything. Probably my second-best documented personal project (or tied for first-best with clojure-multiproject-example).
Things that give me inordinate joy:
- `shite` weighs in at ~300 Lines of Code (and why does it have 240 Github Internet Points, who are these insane people???)
- it is truly "serverless" - I don't run a local dev server even
- it hot-compiles and hot-refreshes on save - fully interactive local authoring (as well as live template modifications)
- since Feb 2022, it broke (only very slightly), after I distro upgraded Ubuntu 22.04 LTS to 24.04 LTS, because pandoc changed its default handling of line breaks, breaking layout of hand-indented "verse" text.
- Under 10 second full site rebuild, with 43 posts totalling over 100K words and over 40 more auto-generated pages (rss feed, various xmls, and per-tag blog post index pages). And I haven't even made it parallel yet. Probably will, if full rebuilds get longer than 30 seconds.
- The resulting site scores top marks on lighthouse and even image-heavy pages render fully in under a second on 4G mobile internet. (zero analytics, or tracking javascript).
It's hilarious --- I've done such sophisticated work for work, but this little piece of personal software is my pride and joy... It makes me grin almost every single day.
May The Source be with you too! _\\ // (yes, I love mixing metaphors)
Ditto. I wanted to show JavaScript text art animation, and could "just" do this:
*** ~setInterval~ and ~setTimeout~ worked just right
These let us call functions that do exactly the thing we want,
viz. punch /[[#the-aesthetic-of-text-art-and-its-animation][characters]]/
into our "live spreadsheet" medium, exactly the way the artist
placed them in the original art source.
These methods can make a CPU sing, but hey, the awesome art
is worth every watt it, ah, draws.
#+html: <div class="box invert">
#+html: <em>Random twitch loop <code>setTimeout</code> and recursion.</em>
#+html: <div id="blink-demo"></div>
#+html: </div>
#+html: <script type="text/javascript">demoBlink();</script>
#+html: <div class="box invert">
#+html: <em>Flipbook-like frame-by-frame animation loop with <code>setInterval</code>.</em>
#+html: <div id="glider-demo"></div>
#+html: </div>
#+html: <script type="text/javascript">demoGlider();</script>
This works very nicely because I've structured my website as "every post is just a microsite". See:
The neat thing about org-mode for writing and publishing (I don't use it for "productivity") is that every time I have a new requirement, there is a solution that I can integrate into my existing writing workflow. And I get multimedia publishing "for free".
So much this. Warts = (software longevity) life lessons. (Though it must be noted that warts != bad design.)
Some years ago, I gave a talk on functional-style shell programming which began with this:
Prelude: Why even bother?
Personally…
Text is everywhere, better learn to process it
The masters already solved it better
Stable tools, well-known warts
Personal/team productivity, tool-building autonomy
To learn about
good and successful design
bad and successful design
computer history
For the fun of it
ref:
Dr. Strangepipes Or: How I Learned To Stop Worrying && Function In Shell (Functional Conf 2019)
Sontag is strongly averse to what she considers to be contemporary interpretation, that is, an overabundance of importance placed upon the content or meaning of an artwork rather than being keenly alert to the sensuous aspects of a given work and developing a descriptive vocabulary for how it appears and how it does whatever it does.
OP here. Ordinarily, I would agree with you, because PageObjects themselves are not composable, in languages belonging to the "Kingdom Of Nouns".
However, the following design, thanks to Clojure's language design, helped address a rather nasty situation.
A tightly scoped Domain Specific Language, over some Types of PageObjects, all of which compose arbitrarily (without breaking value semantics). So, if you wanted the `value` of a Modal box having all sorts of switches, form fields etc., you'd call `value` on it, and it would call `value` on all of its constituents, and return the immutable hash-map snapshot of whatever state it found.
That said, UI testing is a hot mess in general (especially for SPAs). I prefer to avoid automating anything but the "happy paths". IME, exploratory testing is better at sussing out corner cases, and "emergent" misbehaviours. So I do that, in addition to the "happy path" suites. Cue: James Bach et. al. https://www.satisfice.com/
Also I am warming up to server-generated HTML, because I can unit-test that, if I can use `hiccup` syntax + HTMX. In that case, I just make all request handlers spit out HTML fragments as Clojure data, and test those responses in my test suite.
Complexity is what it is...
However, I feel we as software people---executive, product, design, engineering, the whole nine yards---ought to think systematically in terms of Software Debt, as software organisations.
No more "technical" debt, as in "bad code" debt.