More from Ralph Ammer
About 2300 years ago, the great Chinese thinker Xunzi 荀⼦ wrote: “Human nature is bad“. But he wasn’t just having a bad day. The question—Are humans fundamentally good or bad?—is a major fork in the road. How you answer this question profoundly impacts your morals and how you live your life. Previous to Xunzi, another famous scholar had claimed that human nature was inherently good. Mengzi 孟子: Human nature is good The Ox Hill Mengzi had illustrated his idea with a story about a wooded hill. After the trees get chopped down and the sprouts are grazed by animals, the hill appears barren and unfruitful. He compares this hill to someone who can’t bring forth his good character under bad circumstances. For him, goodness is an integral part of every person’s nature. It merely requires the right circumstances to emerge. Goodness will grow forth naturally from every person if no one interferes. Willows and Bowls Someone suggested to Mengzi that a good character had to be forged from a man’s nature like bowls were made from a tree. Mengzi objected that a tree must be violated in order to be turned into useful bowls. He can’t accept the comparison between […] The post Xunzi vs. Mengzi – Are People (No) Good? appeared first on Ralph Ammer.
Should we just live in the moment? In “Matter and Memory” the French philosopher Henri Bergson claims that this is not even possible. 1. Perception is physical First of all: How do we perceive the “current moment” anyway? Bergson suggests that the whole point of perception is action. For example, when some single-cell organism touches an obstacle, it moves away. That is the whole point of perception: to move in the right direction, to find food, to not be food—to survive. Perception serves future action, not insight. Accordingly, our brain is fully embedded in the material world and responds to the movements around it. Bergson refers to such a purely physical reaction as pure perception. Yet he acknowledges that we are more complicated than single-celled organisms. The movements of our environment have to make their way through our complex sensory system with all its twists and turns. And this leaves us more options on how to act. So we don’t just react like a single-celled organism, we can choose from a range of potential movements. But how? We remember. 2. Memory is temporal Bergson distinguishes two kinds of memories: Some memories have become part of our body, they are a […] The post Bergson — Why we live in the past appeared first on Ralph Ammer.
You are awake. You think and you feel. But what is it that is doing all this thinking and feeling? We call it “consciousness” and over 100 years ago the philosopher Edmund Husserl made a bold attempt to uncover its secrets. Subjective experience is private The thing is: Consciousness is not “out there”, it is “in here“. It is personal and subjective. When I say that I like squirrels or that my foot hurts, then you will have to take my word for it. You can’t know what it is like to be me, and I cannot know what it is like to be you. Consciousness can only be observed from the inside, not from the outside. Since we can’t see the world through other peoples’ eyes, their experience remains deeply mysterious to us. Thus we all see the world differently. And this can lead to bitter conflict. Science is based on objective insight One way to overcome such conflict is to take an objective position. We take a neutral view from outside and focus on the things that we can all agree upon. We have learned to see ourselves “from the outside”. In fact, we can build a whole […] The post Edmund Husserl — Consciousness appeared first on Ralph Ammer.
Why do we like images? Because they help us understand things. But what does that mean? Understanding Well, the world is complicated. And in order to make good decisions we need to know what is going on. Language can help us structure the world. So one way to understand things is to find the right words. We perceive colours and shapes, recognise a familiar object, and find the proper word for a concept. Then we can use this word to think and talk about our experience. Philosophers like Immanuel Kant have discussed in great detail how this transition from sensation to thought might work. The point is: When we understand the world, we move from concrete experiences to abstract ideas. Perception and Language One might also put it like this: We rise from the lower level of perception to the higher realm of language. Some people hold language in such high esteem to claim that smart people only think with words, logic or mathematics. Images are useless trinkets for people who are too lazy or too stupid to think. But is that true? Functions of Images Images can support a variety of cognitive tasks. I like to distinguish four different […] The post Show me! appeared first on Ralph Ammer.
More in programming
At first, it sounds obvious: if we want to save the planet, we should do less. Fewer people, less consumption, smaller footprints. I believed this too—so much so that I once thought having kids was irresponsible. But the more I looked into it, the less sense it made.
A deep dive into Testing Library's .toBeVisible() and .toBeInTheDocument() matchers, exploring their differences, use cases, and best practices
A week ago, somebody added malicious code to the tj-actions/changed-files GitHub Action. If you used the compromised action, it would leak secrets to your build log. Those build logs are public for public repositories, so anybody could see your secrets. Scary! Mutable vs immutable references This attack was possible because it’s common practice to refer to tags in a GitHub Actions workflow, for example: jobs: changed_files: ... steps: - name: Get changed files id: changed-files uses: tj-actions/changed-files@v2 ... At a glance, this looks like an immutable reference to an already-released “version 2” of this action, but actually this is a mutable Git tag. If somebody changes the v2 tag in the tj-actions/changed-files repo to point to a different commit, this action will run different code the next time it runs. If you specify a Git commit ID instead (e.g. a5b3abf), that’s an immutable reference that will run the same code every time. Tags vs commit IDs is a tradeoff between convenience and security. Specifying an exact commit ID means the code won’t change unexpectedly, but tags are easier to read and compare. Do I have any mutable references? I wasn’t worried about this particular attack because I don’t use tj-actions, but I was curious about what other GitHub Actions I’m using. I ran a short shell script in the folder where I have local clones of all my repos: find . -path '*/.github/workflows/*' -type f -name '*.yml' -print0 \ | xargs -0 grep --no-filename "uses:" \ | sed 's/\- uses:/uses:/g' \ | tr '"' ' ' \ | awk '{print $2}' \ | sed 's/\r//g' \ | sort \ | uniq --count \ | sort --numeric-sort This prints a tally of all the actions I’m using. Here’s a snippet of the output: 1 hashicorp/setup-terraform@v3 2 dtolnay/rust-toolchain@v1 2 taiki-e/create-gh-release-action@v1 2 taiki-e/upload-rust-binary-action@v1 4 actions/setup-python@v4 6 actions/cache@v4 9 ruby/setup-ruby@v1 31 actions/setup-python@v5 58 actions/checkout@v4 I went through the entire list and thought about how much I trust each action and its author. Is it from a large organisation like actions or ruby? They’re not perfect, but they’re likely to have good security procedures in place to protect against malicious changes. Is it from an individual developer or small organisation? Here I tend to be more wary, especially if I don’t know the author personally. That’s not to say that individuals can’t have good security, but there’s more variance in the security setup of random developers on the Internet than among big organisations. Do I need to use somebody else’s action, or could I write my own script to replace it? This is what I generally prefer, especially if I’m only using a small subset of the functionality offered by the action. It’s a bit more work upfront, but then I know exactly what it’s doing and there’s less churn and risk from upstream changes. I feel pretty good about my list. Most of my actions are from large organisations, and the rest are a few actions specific to my Rust command-line tools which are non-critical toys, where the impact of a compromised GitHub repo would be relatively slight. How this script works This is a classic use of Unix pipelines, where I’m chaining together a bunch of built-in text processing tools. Let’s step through how it works. find . -path '*/.github/workflows/*' -type f -name '*.yml' -print0 .yml in a folder like .github/workflows/. It prints a list of filenames, like: ./alexwlchan.net/.github/workflows/build_site.yml \0) between them, which makes it possible to split the filenames in the next step. By default it uses a newline, but a null byte is a bit safer, in case you have filenames which include newline characters. .yml as a file extension, but if you sometimes use .yaml, you can replace -name '*.yml' with \( -name '*.yml' -o -name '*.yaml' \) -path rules, like -not -path './cpython/*'. xargs -0 grep --no-filename "uses:" xargs to go through the filenames one-by-one. The `-0` flag tells it to split on the null byte, and then it runs grep to look for lines that include "uses:" – this is how you use an action in your workflow file. --no-filename option means this just prints the matching line, and not the name of the file it comes from. Not all of my files are formatted or indented consistently, so the output is quite messy: - uses: actions/checkout@v4 sed 's/\- uses:/uses:/g' \ uses: is the first key in the YAML dictionary. This sed command replaces "- uses:" with "uses:" to start tidying up the data. uses: actions/checkout@v4 sed is a pretty powerful tool for making changes to text, but I only know a couple of simple commands, like this pattern for replacing text: sed 's/old/new/g'. tr '"' ' ' uses: actions/checkout@v4 sed to make this substitution as well. I reached for tr because I've been using it for longer, and the syntax is simpler for doing single character substitutions: tr '<oldchar>' '<newchar>' awk '{print $2}' actions/checkout@v4 awk is another powerful text utility that I’ve never learnt properly – I only know how to print the nth word in a string. It has a lot of pattern-matching features I’ve never tried. sed 's/\r//g' \r), and those were included in the awk output. This command gets rid of them, which makes the data more consistent for the final step. sort | uniq --count | sort --numeric-sort tally. 6 actions/cache@v4 This step-by-step approach is how I build Unix text pipelines: I can write a step at a time, and gradually refine and tweak the output until I get the result I want. There are lots of ways to do it, and because this is a script I’ll use once and then discard, I don’t have to worry too much about doing it in the “purest” way – as long as it gets the right result, that’s good enough. If you use GitHub Actions, you might want to use this script to check your own actions, and see what you’re using. But more than that, I recommend becoming familiar with the Unix text processing tools and pipelines – even in the age of AI, they’re still a powerful and flexible way to cobble together one-off scripts for processing data. [If the formatting of this post looks odd in your feed reader, visit the original article]
JavaScript went against the grain in only using floating point numbers initially, and now we pay the price
Immortality always sounded like a curse to me. But especially now, having passed the halfway point of the average wealthy male life expectancy. Another scoop of life as big as the one I've already been served seems more than enough, thank you very much. Does that strike you as morbid? It's funny, people seem to have no problem understanding satiation when it comes to the individual parts of life. Enough delicious cake, no more rides on the rollercoaster, the end of a great party. But not life itself. Why? The eventual end strikes me as beautiful relief. Framing the idea that you can see enough, do enough, be enough. And have enjoyed the bulk of it, without wanting it to go on forever. Have you seen Highlander? It got panned on its initial release in the 80s. Even Sean Connery couldn't save it with the critics at the time. But I love it. It's one of my all-time favorite movies. It's got a silly story about a worldwide tournament of immortal Highlanders who live forever, lest they get their heads chopped off, and then the last man standing wins... more life? Yeah, it doesn't actually make a lot of sense. But it nails the sadness of forever. The loneliness, the repetition, the inevitable cynicism with humanity. Who wants to live forever, indeed. It's the same theme in Björk's wonderfully melancholic song I've Seen It All. It's a great big world, but eventually every unseen element will appear as but a variation on an existing theme. Even surprise itself will succumb to familiarity. Even before the last day, you can look forward to finality, too. I love racing, but I'm also drawn to the day when the reflexes finally start to fade, and I'll hang up the helmet. One day I will write the last line of Ruby code, too. Sell the last subscription. Write the last tweet. How merciful. It gets harder with people you love, of course. Harder to imagine the last day with them. But I didn't know my great-great-grandfather, and can easily picture him passing with the satisfaction of seeing his lineage carry on without him. One way to think of this is to hold life with a loose grip. Like a pair of drumsticks. I don't play, but I'm told that the music flows better when you avoid strangling them in a death grip. And then you enjoy keeping the beat until the song ends. Amor fati. Amor mori.