When Open Source Maintainers Don’t Understand Community is Important

This is just to vent frustration at a thoroughly stupid experience I had recently. A portion of that stupidity is me failing to read something correctly, but I’m just really stuck on the stupidity of the response to me asking for help:

I asked for clarification, and was told to go away.

My reaction clearly indicates that I am not undrstanding something, and I even tried to give context to where I’m coming from so that it would be easier to spot what I misunderstood, but instead I was told to go ask a bot.

And then they blocked anyone from ever asking for help again.

The public is not allowed to open issues now.

What’s most frustrating to me about this is that it coincides perfectly with another issue I ran into today where I couldn’t add an important detail to an old issue. Past conversations are useful to people looking for assistance, especially when one solves their problem and explains it. When I am blocked from replying to something with a solution, anyone in the future experiencing the same issue is likewise blocked from finding the answer.

I now know what I messed up, but I’m not allowed to pass that knowledge to the future, because I was confused and made a mistake in how I asked for help.

There’s another layer to this that is often ignored: When this is the response the average newbie gets when they first try to contribute, they are encouraged to never ask again, or in the case of submitting pull requests, encouraged to never try to help again.

When open source maintainers discourage newbies, they cannibalize the future of their software.


Okay, that’s my entire point, but I also encounted some funny things as part of this.

What is a contribution? GitHub doesn’t know!

I think it’s interesting that GitHub says the repo limited opening issues / commenting on issues to past contributers, but I am a past contributer. GitHub clearly considers issues to be contributions, as every profile has a graph showing issues as part of their contributions:

My contributions: 89% commits, 11% issues.

AI tools can be very powerful, but they can also be very stupid

Earlier today, I tested Perplexity AI’s capability to answer a few basic questions easily answered through traditional search engines, such as which insect has the largest brain and which country is the current leader in development of thorium-based reactors. The results? It doesn’t know ants are insects, thinks fruit flies have large brains just because they have been the subject of a large number of studies, and ignores India in favor of China because western media reports on China a lot more.

But you know what, I wanted to test this asshole’s suggestion to ask ChatGPT about my problem, and surprisingly, it gave a very clear and accurate response!

ChatGPT points out what I misread: I have to clone the repo AND run NPM, not just run NPM.

When you offer binaries for a project, they have to actually exist..

To be fair, this is a fairly recent change to the ReadMe, but maybe you should publish binaries before advertising that you publish binaries?

Getting Started: Download a release binary and run it. Simple.
The advertised binaries don't exist.

Installation and usage aren’t the same thing

It’s understandable to be confused about whether someone has correctly installed something, but after confirming that installation has worked, ignoring the question asked is unhelpful to say the least.

After confirming that I've installed it, my question is ignored.

Equality Has Many Definitions

This is a RAID post. Contents are brief thoughts based on few sources, and have not been checked for accuracy or usefulness.

These notes are based on a section of Equality by Darrin M. McMahon. I haven’t finished reading it, and a bug deleted most of my notes from the first ~200 pages, so it is even less complete than it might otherwise be.

People are different, and this makes them inherently unequal. This has been used to justify bigotry on arbitrary differences throughout history, but declaring equality of all doesn’t make people equal either. Everyone has needs and capabilities, and the only path to equality is to have all people use their capabilities collectively to fulfill their collective needs.

Stalinism took “From each according to their ability, to each according to their need.” and replaced the word “need” with “work”. By including this seed of meritocracy, anyone injured, disabled, or elderly is excluded from equality. (I think every person has a phase where they see meritocracy as ideal. Fortunately, most people grow out of this phase.)

Nazis promoted equality of a few at the expense of everyone else. (How equality has been used throughout history changes. It is important to recognize that it means different things to different people.) Fascism creates a meritocracy exclusive to one class, relying on the existence of outsiders (who must be murdered1). In this way, fascism must shrink the accepted class to have more outsiders, and eats itself.

We claim all nations are equal, while propping up some, sabotaging others, and we can all see that nations are not equal. WWII’s devastation increased equality (see “four horseman of leveling” in Quotes). Post-WWII, economists claimed that industrialization forms a natural progression of brief extreme inequality that quickly brings in equality. (This is an obvious lie.) At the same time, economists claimed that it was better to make a nation wealthy than to fix its inequality, and that commerce is a leveling force. “When a rich man sells to the poor, they become equal.” cannot be true, and yet it was the predominant claim.

Quotes

  • “self-love is the great barrier to full human equality” I see in many people, especially myself, a critical lack of self-love, so this stood out to me as worth investigating further. It may not be true, or it may be more true than I am capable of recognizing right now.
  • “Christianity is Communism” If you research when and where Christianity was formed, the people were living under a form of communism.2 The ideals of Christianity are communist ideals, but have been changed and replaced by centuries of adaptation and interpretation.
  • “iron law of oligarchy” In every government, an elite few control all. There are many systems to stop this, but they have all failed so far.
  • “four horseman of leveling” – war, revolution, state failure, disease. These are all common things that have caused increases in equality by hurting everyone.

Questions

  • Does communism only work at small scales? It is implied to have only worked when implemented by communities instead of countries.
  • Does Marxism rely on individualism? The more I learn, the more I see that individualism is the biggest threat to progress. (Ever heard “divide and conquer”? Individualism IS self-division – a destruction of community. It makes us weak.)
  • What makes immigration “good”?3 From my education, I “know” that immigration has always had benefits, but what are those benefits? Why do we call them beneficial? As far as I know, the benefit has always been cheap labor (exploitation of immigrants). I want to challenge my education, and learn more about the complexities of immigration. (There is never a valid reason to stop immigration.)
  • Should we not want greatness? What IS greatness? Nietzsche argued for a constant personal struggle to achieve greatness, and against many institutions that improve equality. If seeking greatness requires sacrificing others, should we ever want it?
  • What was good/bad about the “New Deals”? They compensated for a destroyed economy, and produced infrastructure still used today, but what were the exact short-term and long-term effects?

Further Reading

  • Capital: A Critique of Political Economy by Karl Marx

Footnotes

  1. Fascism relies on exploitation of the unaccepted classes, which often literally involves mass murder, but also makes the unaccepted people leave. This is why fascists inevitably shrink their accepted class.
  2. Romans were the capitalists of their day, exploiting the people that became the first Christians. Communism is a broad and complex subject. In this context, communism is being used unrelated to the way it is used as a classification for modern countries.
  3. A partner reminds me that diversity is an inherent good, and that immigration increases diversity. (At minimum, diversity brings new ideas and perspectives into focus, and increases resiliency.)

(It’s kind of difficult to keep motivation when hard work is unceremoniously destroyed by a glitch..)

Reading, Absorbing Ideas, Distillation

Learning is a long and complex process, and usually involves asking far more questions than getting answers. Sometimes, having notes can shortcut the most difficult parts of learning (like reading a thick and detailed book). Of course, shortcuts come with downsides, like inaccuracy.

I’ve been publishing some of my notes in their raw form instead of trying to make a “perfect product” out of them, but these are not easy to find due to how they’ve been published, and I am disorganized.

I’ve thought of this blog as a place for well-thought-out posts only, but that basically means I don’t publish anything, and the exceptions rarely meet my own required quality. I think I can solve a lot of my issues here by being willing to post thoughts that haven’t been fully designed, like this mess (but legible and formatted based on the source of each thought):

Illegible notes based on Equality by Darrin M. McMahon.

Each of these posts will be prefixed by a quote to indicate that their contents aren’t made of fleshed out thoughts:

This is a RAID post. Contents are brief thoughts based on few sources, and have not been checked for accuracy or usefulness.

Notetaking in Public

I’m stealing Nicole van der Hoeven’s idea: Post your messy in-progress notes in public.

I Spent Two Hours Learning How to Take a Break Instead of Taking a Break

And so you hopefully don’t waste the same amount of time, here are just the conclusions:

Take breaks every 20 to 70 minutes. Finding the right frequency for you may take trial and error. Multiple sources agree that something near 50 minutes of work with 10 minutes of break works well. The Pomodoro technique combines more frequent shorter breaks with infrequent longer breaks, and is commonly used. The longer you go between breaks, the longer your breaks should be.

A break is only effective when you do something different from what you’re doing now. The primary differences that matter are using different areas of the brain (or not trying to utilize your brain during a break), a difference in eye-focus (stop looking at screens if you were, look far away if you were focused on something right in front of you), and a difference in physical activity (move more if you weren’t moving, or stop for a bit if you were).

(Vacations have beneficial effects, but these seem to be limited in scope and duration. I believe this take is missing important nuance.)


If you wish to read all my notes on this topic, they are publicly available here. (Note: In case that website goes down, I do regularly back up my notes (and blog posts) on the Internet Archive.)

LuaJIT Strange & Unpredictable Behavior in table.sort

A quick story about discovering where Lua’s table abstraction fails to work.

In Lua, arrays should always be initialized sequentially, and should never have a nil inserted.

(The code behind this adventure starts on line 128 in one commit, where a crazy work-around was used to get what I wanted. This was eventually fixed in commit 8b8f36b (though accidentally sorting the wrong direction at that point). I provide these links to remind myself what happened, and so that if someone more knowledgeable than me wants to figure this out, hopefully they can. I’ve also made sure those links have been archived by the Internet Archive so they remain available even if the project is gone.)

While working on a prototype, I needed to sort a list of integers so that I could count the sum of the top thousand items in an array of ~40 thousand items. This list had empty indexes (or holes) within it, so I wrote a for loop to fill them with zeros and then called table.sort. It errored from trying to compare with a nil. This was confusing because I had a well-defined length that was used to fill holes, and the way Lua works, any hole in the list should be the end of what Lua recognizes as a list. As far as I knew, standard functions don’t allow holes in lists by ending at the first hole encountered.

for i = 0, list_length do
  if not list[i] then
    list[i] = 0
  end
end

I was further confused when I added debug code to check the list for nil values by iterating over it and printing every value in it: No nil values existed. The strangest part was when I passed my own sorting function to table.sort specifically to handle nil values and it created the same error. I worked around this by brute-forcing it with an incredibly inefficient thousand traversals of the entire list, removing items as I found the maximum each time. It’s a prototype, so whatever.

It didn’t sit right with me, especially because I couldn’t figure out how this was occurring. It’s incredibly rare to find an actual bug in highly used production software like programming languages, so I doubted I’d found an actual problem. Later, I realized I had added a zeroth element to this list, and Lua starts counting at 1, unlike a lot of programming languages. Removing this changed nothing, so I double-checked my assumptions and found that now nil values were showing up – and this is after no code changes except adding a for loop to print values.

I wrote a new sorting function that checks more thoroughly for nil values (I think the previous attempts at that failed because I’d made some simple error in how I was thinking about it). It worked. But then I found the loop whose code I’ve shared above, where holes are filled with zeroes. It had been a while, so I was very surprised to find what should have fixed things right there doing nothing.. somehow. I mentioned this in a group chat, and someone suggested replacing list_length with #list (the # operator returns length). The problem is that Lua stops counting at the first nil, so that should do nothing.

There’s also the possibility of an off-by-one error, those are very common, but I had assumed this would happen at some point and made sure all of my functions and loops checked one element earlier than necessary and one element later, so that if I checked too much – just extra zeroes, but I couldn’t check too little.

I wasn’t satisfied by all the nil values being there after a loop that replaces them with zero, so I tried making a loop at the top of the code that prefills a much longer list than I actually needed with zeroes. Suddenly, I didn’t need a custom sorting function. So why does filling the list with zeroes work in one place, but not another?

How Objects Work in Lua

In Lua all objects are called tables, and can contain an array-like section and arbitrary key-value pairs in a hashmap. It doesn’t really distinguish between these except as an optimization, under the hood it tries to guess how you intend to use the object and assigns values internally differently depending on what index you’re using. I thought that in practice, this means integer indexes are handled like arrays, and non-integer indexes are in the hashmap. I thought that maybe because my code was selecting integer indexes in a completely random order, it treated these as a hashmap instead, somehow leading to ignoring attempting to fill the holes – because there weren’t any holes, or the holes persisted because only part of the indexes were treated as an array.

Lua’s tables are an abstraction meant to make writing code easier, and for my years of working with them, they do that quite well, but maybe this is where the abstraction leaks? (All abstractions leak: They have some condition(s) where you end up needing to know how they work underneath, even though the point of abstraction is to not need to know how it works underneath.) Perhaps arrays are only recognized when they’re initialized sequentially, whereas my code initialized them in a random order? Either way, the error I started with manifests as “An array of integers can’t be sorted because part of it is undefined – even though every element is defined when iterated over.” which is not supposed to be possible.

There’s also the detail that in Lua there is not supposed to be difference between something having a nil value and it not existing at all. There is a difference, but it should be impossible to tell the difference or for the difference to matter in your code. It is possible that this alone is why I had this problem. Changing a value to nil inside an array table can cause all values within it to be converted to a hashmap, or some of them, or none of them. Again, this shouldn’t matter (other than a difference in speed which is usually unnoticeable), but it might matter.

I wrote a minimum test case to see if my hunch was correct, but it works when I expect it not to. I’m lost. I have an explanation that informs how I should code so that it works – and it does work, but because that explanation fails when tested, it seems incorrect. I want to know what’s really going on, but it requires a depth of understanding that I lack, and effort that I do not have the time and energy to go into.

I also learned that Lua defines this kind of behavior as “strange and unpredictable behavior” instead of undefined behavior, because undefined behavior means that an entire program can fail to function correctly do to one element with undefined behavior (even when that element is not accessed), whereas in Lua, a table exhibiting strange and unpredictable behavior doesn’t affect the rest of the program. So, if you can work around it, it’s okay.

At this point, I’m happy enough telling myself that arrays should always be initialized sequentially, and shouldn’t have nil elements ever. If I follow that, I probably won’t run into this. But.. if you’re reading this and understand what’s really going on here, please tell me.