Q: Hey! Should I read this?
A: Perhaps not. Perhaps. I use this page as a low-filter, low-threshold way to get ideas out. Capture ideas, incomplete as they are. Growth and nurturing is a separate process. Filtering, curating, organizing — that’s for later. The reading experience might feel like a stream-of-consciousness endeavor — with less flow, less feelings, less poetic content. In other words, messy, without the good sides of messy. Still, I choose to make this public, because I believe public should be the norm, not the exception.
🐉
I feel shackled by pressure for specificity. Always be specific. Specific is better. Don’t be vague.
Specificity expels indirection. Indirection is core to design.
If we lazer-focus on the specific, we’ll ignore problems with a longer feedback cycle time than some arbitrary limit.
Statement: “don’t build something for yourself – you’ll ignore users”
Response: “no – DO build product for yourself – but design in the flexibility as indirection. Don’t force your users into your workflow. Doing it for yourself is not workflow design - it’s capability design.”
By building in flexibility — indirection — at the right layer, we decouple the product, and give ourselves leverage.
I’m better when I have fun.
I have fun when I build stuff for myself and others.
∴ I should build stuff for myself.
Commonly discussed feedback loops:
Uncommonly discussed feedback loops:
(moved from separate page)
We explore how Pandoc supports embedded code.
We can write Clojure:
defn act [& commands]
(;; code
)
Or Python:
def act(*commands):
# code
pass
Or even javascript:
function act(commands...) {
// code
}
Another morning.
Possible solutions:
Outcome - less messy front page.
Right now we’ve got this:
Intent: bring ideas to life. Discuss, sharpen, play.
Status: very much work in progress. Please advance at your own peril.
Pages:
- aphorisms
- emacs
- feedback-loops-api-design-how-it-works
- hourglass-architecture
- journal
- knowledge-worker
- opt-in-hierarchy
- options-to-the-max
- orthogonality-enables-optionality
- product-for-developers
- truth-descriptive-prescriptive
- unix-signals-crash-course
- website-so-what
Possible next steps:
- Write real content
Possible improvements:
play.edn
file?Backwards compatible path - existing behavior prevails, title is “settable” from play.edn.
The root HTML file will now depend on all the play.edn
files. Perhaps use SQLite for caching?
Not now. I want good performance under scale. Performance is important.
I can just opt for manual indexing if the need arises.
Outcome - better titles. Order. First create a play.edn
file manually. Then create the proper
title for that file. Run index.clj
by
hand.
Dump:
So …
I’d like a teod/apply-on-save-mode
.
Perhaps I made it work?
Or?
Nope. Back to manual teod/apply it is.
Morning / afternoon / whatever.
🤠
How are we coming along?
play.clj
script with a CLI.Next steps?
page
command automatically
categorize stuff as “don’t mind me”Page | Category | aka |
---|---|---|
https://play.teod.eu/emacs/ | Rambling | |
https://play.teod.eu/aphorisms/ | Page | |
https://play.teod.eu/feedback-loops-api-design-how-it-works/ | Article draft | |
https://play.teod.eu/hourglass-architecture/ | Ideas & capture | Narrow waist |
https://play.teod.eu/opt-in-hierarchies/ | Ideas & capture | |
https://play.teod.eu/orthogonality-enables-optionality/ | Article draft | |
https://play.teod.eu/product-for-developers/ | Article draft | |
https://play.teod.eu/journal/ | Rambling | |
https://play.teod.eu/unix-signals-crash-course/ | Article draft | |
https://play.teod.eu/knowledge-worker/ | Article draft |
How do we tag?
By form:
:form :rambling |
:form :article |
:form :explore |
:form :unknown |
By readiness:
:readiness :in-progress |
:readiness :published |
By language:
:lang :no |
:lang :en |
Dump -
distributed ${ARTICLE}/play.edn
files
are “near” to the article (nice), but tedious to batch edit
batch editing is nice in a table
A normalized model is EAV.
EAV example:
:id "emacs" :title "(Doom) Emacs learning journal"
:id "emacs" :form :rambling
:id "emacs" :readiness :in-progress
What are nice ways of batch editing?
One big text file Excel table SQLite?
How should lines be deleted?
In Dired, simply d
the line, then x
to apply with confirmation In Magit, c c
to commit, C-c C-c
to apply
I could simply try dumping all the data into SQLite and see how that works out.
I have:
Metadata per page some pages
So - simple, flat model.
I could build
Files -> SQLite SQLite -> files
Do I want “apply everything” or “apply partial”?
I could implement “apply everything” in terms of “apply partial”
First delete all the play.edn
files
Then apply partial And confirm changes in Git.
play.edn
to ensure link integrity./play
API
draft$ ./play2.clj relations :from :files :to :lines
:id "emacs" :title "(Doom) Emacs learning journal" :form :rambling :readiness :in-progress
:id "feedback-design-impl" :title "Feedback loops, API design and how stuff works"
...
Created the lines mode - and more.
Mode | Read? | Write? | Purpose |
---|---|---|---|
:files | y | y | play.edn files is the main storage |
:lines | y | y | lines give a concise overview |
:table | y | y | table is great for batch editing |
:pretty | n | y | :to :pretty is great when devleoping a reader |
This almost looks like an hourglass architecture :)
relations interface in the middle.
I’m happy with the design.
idea - dynaimc programming isn’t lack of types. Dynamic programming is options to do flexible stuff.
Option - work on data structures rather than types. XML - static types for everything, or a dynamic tree? JSON - types for everything? Alternative formulation - serialization for free
Option - dynamic runtime. Dynamic languages often support interpretation / dynamic recompilation
Option - extend language when required. Embedded DSLs are just data (Or macros, but macros can be complex)
Option - use schemas directly for validation rather than types
Examples? Hmm Python? Clojure? Javascript?
I want to give Ole Jacob a big JSON file he can build UIs on top of
play.teod.eu/iterate-knowledge-archipelago.json
rich entity semantics - “url” “title”
& filter on tags
I want to get more info when I generate pages. This should be possible:
./play.clj page compuational-engineering :title “Computational Engineering”
And it should also write :author-url and :created-at.
Are they even required any more?
I haven’t used any of them in a long time
Makefile works well
Action: delete em.
☀️
For me:
Written for myself | 10 |
Shared with others | 1 |
Why?
Working on my own ideas / perception / intent is something I’d like to do with an internal feedback loop.
Why?
Hmm, good question.
Well, easy answer. Because I don’t get anywhere as fast ahead through conversation with others.
Why?
No, actually, that’s not it.
And amount of written text is the wrong metric
Effort is the right metric
For effort, it’s perhaps 50/50
50 % internal
50 % external.
I prefer writing to thinking when iterating internally.
I prefer speaking to writing in conversation
I think? I’m not quite sure.
That basically means they are missing Org-mode.
So perhaps “I dislike anything that doesn’t have Org-mode” is better.
😆
I feel shackled by pressure for specificity. Always be specific. Specific is better. Don’t be vague.
This feels like a statement that sometimes a bad abstraction is required to get to a good abstraction. Also, I hate being forced to do stuff.
https://irreal.org/blog/?p=10050
and https://pubs.acs.org/doi/10.1021/acscatal.5b00538
and https://www.technology.matthey.com/article/66/2/122-129/
And “which is the first subset of Org-mode that should be supported?” https://gitlab.com/publicvoit/orgdown/-/tree/master
Should be worthy of a page on its own.
Also paves the way for what I can do with play.teod.eu.
Also perhaps worthy of publishing to the Clojurians Slack? Hmm.
Driving in Troms, with Tjerand and Torstein.
npx seems to look for new versions on each invocation. I can’t use the following offline:
$ cat preview.sh
#!/usr/bin/env bash
npx live-server --no-browser --port=3000
So … what do I want? Just having the dependencies available offline would be nice, really.
Options:
node_modules
, package.json
and package-lock.json
.ag
is using Org-Roam quite heavily. He
separates between:
And says that there’s no semantic difference between those three categories and:
Hmm, I think I’ve actually landed on that same structure myself in Roam. Fleeting notes go on the Daily Notes page. Permanent notes are entities. Project notes are one big hierarchy.
How does that map to play.teod.eu?
Fleeting notes go into the journal. No new entities. Permanent notes get their own page. It should be possible to link to permanent notes! Project notes get a page per project. That page is deleteable or “removable from index”.
Question: “in what context do I want to re-discover this piece later”. Then – establish links to all those contexts.
I really don’t like UPS.
I could create some simple Emacs lisp commands for that which shell out to babashka.
Hmm.
How do others do it? I tried looking at the Doom Emacs creator
dotfiles, but I didn’t find any Emacs config. https://github.com/hlissner/dotfiles/tree/0df9027010b424410a4622eba54b979c256f0efb/./
I guess his Emacs config is just Doom. What about https://github.com/tecosaur/? He
just has a big org-mode file. What about https://github.com/org-roam/?
Good. Toplevel org-roam.el. Then (require 'org-id')
and
others.
Why?
It’s the next step, I think. I know how to do basic stuff, I don’t know how to do interactive stuff. I love how magit works. How dired works. Dired’s view over the file system, the ease of moving around.
So … I probably want a major mode too. Haha.
:)
Git knows this.
I would like: input folder path, output last changed timestamp.
Purpose: sort, enrich :relations.
Treat :changed the same way as I’m treating :id now. It’s a special
tag, and should not be written down. When writing lines back to files,
dissoc
the :changed
property.
named ideas have a deeper meaning. They have an URL, and can be linked to.
project journal is temporally indexed. Date up top, topic below. Project-scope rambling.
project problems is a mutable approach to attention design. It does not function as a ledger. Rather, it is meant to be changed. Problem-scope attention design.
journal is the temporally indexed global catch-all thing. Put things here when in doubt. Global-scope rambling.
problems is a global list of things that want attention. Global scope attention design.
teodorlu@teod-t490s ~/tmp/temp-2022-07-15/prompt % prompt off
% PROMPT="$ "
$ echo hello there
hello there
I don’t want to end up stuck. In a context where there’s no novelty. Where there’s nothing I can learn.
What does such a context look like?
Is it closer to a research lab than a product company? Can there be both?
ec Nextcloud/store/elementsofclojure.pdf
“Indirection is abstraction”
Indirection, also sometimes called abstraction, is the foundation of the software we write. Layers of indirection can be peeled away incrementally, allowing us to work withint a codebase without understanding its entrirety. Without indrection, we’d be unable to write software longer than a few hundred lines.
Huh, this names something I’ve seen. Python scripts written by civil engineers. One big for loop, with some clauses.
Advantage: straightforward. Disadvantage: Inflexible. Lesson: use indirection / abstraction to make code flexible.
Grateful.
?
I wrote something I thought was of value:
- Make sure your note taking system supports your goals. My goals: (A) assist my learning, (B) easily share content and get feedback from others.
When you produce content, consider (A) what you want to achieve by producing the content, and (B) how you want to find the content later.
Use one global namespace for named concepts. Category / taxonomy / tags belongs in metadata.
Why the goals? If your system supports your goals, you will continue to use it and get value from it. If your system doesn’t support your goals, it becomes tedious to use, and you’ll abandon your notes.
I encourage you to put your notes publicly on the web. Public notes have URLs, and there’s no easier way to read content. You’re going to remember notes.yourname.com/THING, or just go via notes.yourname.com to list / search.
My information architecture consists of named concepts, journals and metadata.
Named concepts is the top level. Wikipedia uses this structure. There’s one global namespace with sufficiently qualified names. You are going to remember your note by this name. Disambiguate in your global names.
Journals are organized by date. The advantage of journals is that you don’t have to name anything. In general, it’s nice to start with a journal, and collect named concepts on demand. Journals don’t have to be discoverable.
Metadata helps you discover and index your notes. Categories and tags go here. But don’t go nuts on categorization, think about what those categories should achieve. Remember the fact boxes on Wikipedia? Those are driven by concept metadata. Sometimes it’s better to embed a table or a nested list on a concept page than introduce metadata. “Is this helpful to understand the concept?” - put it on the page. “Is this helpful to find/index your content?” - it’s metadata.
Let’s say you want to learn FUSE (https://en.wikipedia.org/wiki/Filesystem_in_Userspace). Create a journal page for learning FUSE, and tag it as “open problem”. Make sure you can list open problems. Each time you’ve got some time, open your FUSE journal, and work to understand something. Read the man page. Read wikipedia. Read the source. But annotate! Take notes in your journal as you go. When you revisit your FUSE journal, you can easily rediscover where you were last time, and decide where you want to go next.
Didn’t get any comments.
Am I dissatisfied? Doesn’t feel that way. Am I surprised? Yes, perhaps. That’s imprecise. Yes, I’m surprised. This is something I believe strongly in.
Am I disappointed? No.
xx
bimodal strategies
deep work, tactical initiatives, strategic initiatives
Applying bimodal strategies to the design of the daily effort.
Squirreltime – topic of stuff :)
Burnout, meaning and deep work. Reflecting on the last half year.
How is a perfect day structured?
Principles to prevent burnout, mess and loss of the strategic picture.
Hello.
Live.js: https://livejs.com/
I’m hosting with Cloudflare.
Problem: there’s no live-reload.
Diagnosis: Cloudlfare sends the same headers on each request. That’s meant to disallow caching. But in my case, it causes cache invalidation to never happen – opposite of the intended effect. I could fork live.js if I want, it’s small.
To get Live.js working with Cloudflare, I need Cloudflare to produce
correct etag
headers. That means I need to
disable some Cloudflare stuff.
General Cloudflare Etag docs: https://support.cloudflare.com/hc/en-us/articles/218505467-Using-ETag-Headers-with-Cloudflare
Cloudflare pages dog, mentions etags: https://developers.cloudflare.com/pages/platform/serving-pages/
Pretty pleeeease
Still no etag header on the responses.
is it automatic or not?????
Woah!
:)
Also, “how to help”.
From Aphorisms:
10 - When in doubt, do that which builds trust.
11 - When still in doubt, do that which reifies and distributes intent.
12 - When still in doubt, reduce WIP.
13 - When STILL in doubt, improve your specific & general feedback loops.
xx
Target audience: xxx
Because taking notes is 90 % for the process, and only 10 % for the resulting artifact.
Because simply copying does not help you reify your taste. It does not help you to cultivate your taste.
options
choice
se Terminalen: Hvordan løpe med motorsag. Jeg har lyst til å bruke dingsen til Magnus. Det hadde vært fint. Men … hvor var det vi gjorde det? Vi flyttet det til et Iterate-repo, vi.
“Cultivate your aesthetic”, visa said. I wanted answers. I wanted a preference. So I figured, Okay, let’s try that. Let’s dig in.
I had no idea what that little germ of an idea would do to me.
Now, it has changed how I think. I find more joy, meaning, purpose and connection in each day. I enjoy doing my work. I’m not doing it for somebody else, I’m doing it for me.
Yet — at times, the devil in me shows his face. His strikes are more powerful. His tongue sharper, his arguments bear more conviction than before.
I realize that I cannot be only kind.
As I started to write today, I expected to want to explore bitterness. Bitterness at lack of quality. Bitterness when those around me don’t care.
I had a lang walk+talk with Sindre today. We talked about things I’m frustrated with. (and we bumped into Ida, which was fun)
I have this model of human relationships. Your relationship with someone has three attributes:
I find that trust and shared intent can be built. And building those are sort of … easy. Well, it’s not exactly easy. But it’s soluable, in the words of David Deutsch. It’s work. It’s something you can do. Improve trust and shared intent every day, and you’ll succeed. (or figure out that this is someone you don’t want to work with)
I digress.
I don’t think shared sense of quality can be built. I think shared sense of quality is discovered. You figure out what someone likes, explore their kneejerk reactions. What do they deliver, when given freedom? Is it any good?
Making an explicit effort to cultivate my own aesthetic has sharpened my inner critic. I see clearly what I like and what I despise. And my reaction to content without substance is bitterness and disgust.
Is this my new normal? Is disgust the price to pay for joy? Does a tree with branches reaching to heaven necessarily need roots anchored to hell?
We’ll see.
Oh, we’re not quite done. The eagles have come, saved the day, and we wake up in Rivendell.
I actually feel good now. Being dead serious, actually honest about that sense of quality. I felt like an ass when I was in the heat of the moment. Now I feel … relief. I feel good. I didn’t expect that.
I bet there’s a lesson in here somewhere.
Until next time,
Teodor
we wake up again, this time in the Shire. Yet Another End That’s Not An End.
I read this:
feeling proud of your work is critical for any ambitious/high-achieving person. for this type, it’s not about the hours put in, it’s about the *feeling they get out* of doing the work. and if they’re not interested in the work, it’s hard to make it phenomenal and be proud of it.
— Isabel⚡️ (@isabelunraveled) November 7, 2022
The War of Art introduces “territorial orientation”. Here’s a quote from the chapter The Definition of a Hack:
In other words, the hack writes hierarchically. He writes what he imagines will play well in the eyes of others. He does not ask himself, “What do I want to write? What do I think is important?” Instead, he asks “What’s hot, what can I make a deal for?”
The hack is like a politician who consults the polls before he takes a position. He’s a demagogue. He panders.
“so what?”
Yeah, that’s the feeling of quality and lack thereof. The joy of doing something worthwhile, and the disgust of wading through swamps.
“so what, you feel like complaining?”
No. I like where I am. I like where I’m going.
And I like that I don’t like everything I see.
bitter can be good. Ginger. A good beer. Grapefruit.
We had some snow! Now we have some gray stuff.
cond->
confusionI expect the following to evaluate without crashing.
list 1 2 3)
(cond-> (number? inc)
Do you know what? It crashes! Who would have thought.
1. Unhandled java.lang.ClassCastException
class clojure.lang.PersistentList cannot be cast to class java.lang.Number
(clojure.lang.PersistentList is in unnamed module of loader 'app';
java.lang.Number is in module java.base of loader 'bootstrap')
I thought
(cond-> form condition transform)
was equivalent to
if (condition form)
(
(transform form) form)
, but it appears I was wrong. Not sure why.
:)
Proposed principle: don’t ask people for stuff in public.
Why? I was in an E-mail chain with five other people. I don’t like those E-mail chains.
Proposed principle:
Why? It decouples “is this disrespectful” from other questions as “what is good?” and “what is practical?”.