13 Comments
User's avatar
Victor Maia Aldecoa's avatar

I just saw sokol and clay for the first time, and it looks like a completely new world to me. It's so refreshing to discover something like that after 12 years of career! Thank you for sharing.

Expand full comment
dechichi's avatar

Had the same thought when I first discovered these kind of libraries! I particularly like how easy is to integrate them: simply include the header file and define a macro when you need the implementation.

Expand full comment
Aleksandr Vasilenko's avatar

Another issue is you are forced to stick with a pattern that the library uses. Switching libraries is often a massive refactor. And when you choose a library version you rarely upgrade it, eventually it becomes massively outdated and bugs and security vulnerabilities are found, but upgrading the library version often leads to some refactoring. At the end of the day you were better off just writing it yourself.

Expand full comment
Matthew's avatar

I've been thinking of writing something like this myself. I'm glad someone much better at coding than me has done it. Sometimes I feel like I'm going mad watching people download 1k+ react dependencies for a CRUD app, so seeing others echo my feelings on this is nice.

Expand full comment
dechichi's avatar

Years ago when I were questioning some of the things I was taught as a programmer I found a experienced programmer confirming my suspicions as well, which gave me the confidence to keep digging. Glad I could help!

Expand full comment
Dutton Industrial's avatar

Great article!

Now a hastily worded thought that this article inspired... thank you!

Libraries start out as a piece of a specific program. During development the developer sees a cut-line in their program, where all things on side 1 have commonalities and thus "should" be in a library. Side 2 becomes the unique code that represents the actual program. As part of this proces side 1 becomes a generality however what is unseen is that it is also a dual to THE program. It has assumptions and axioms embedded within it that reflect the original "program."

Once split off this library is then incorporated into new programs which bring along with it an unintended shadow of the original program. Thus the new program using the old library will now structurally be forced to somewhat resemble the "old" program even though it has nothing in common with the "old" program. This residual structural influence then creates a limit to the new program. The designer of the new program will then hit unforeseeable boundaries. I've been here many times... it's like a force field. The new program wants to be a certain way. The library needs your program to be a certain way. No bueno.

The older the library, assuming active development, the less "residual shadow" it will have within it.

If you depend upon 10 libraries then your program can only live within the venn diagram of the intersecting shadows of the programs that these libraries were pulled from. It is probably limiting in a somewhat exponential way. This is why an ambitious never before seen program not only won't have many dependencies, but actually cannot. You won't be able to express this program in the terms that the dependant libraries can actually function within.

Expand full comment
Ben Kimble's avatar

Great article. I’m not going to lie, though, the 12 year old in me expected to open it and see “your mom” to the right of node_modules.

Expand full comment
BenZ's avatar

The correct answer is to use whatever you need for the specific project... not all projects have very high performance requirements.

I believe that if you're making a project for other people to code in (game engines) the correct answer is to have both a low level hard to use library and a high level easy to use library (that uses the low level one) to satisfy both users.

Expand full comment
dechichi's avatar

That's true, but the main things is that programmers should be asking this question, and I feel most don't.

how much am I paying for this library? is it worth the cost? what is the cost of writing the subset of features I need? if the answers point towards using the library being a reasonable trade-off for the project, then all good.

Most of the time I personally think the trade-offs are not reasonable, but that's just my personal preference.

Expand full comment
Victor Maia Aldecoa's avatar

Nice!

Expand full comment
Alessio's avatar

Nice post.

I saw that thread on X, so I have a technical question that goes beyond this article, as it was mentioned there.

Since I use a similar command-line parser, how do you compare strings ?

Do you use strcmp, or do you use a hash?

If you use the latter, why?

Is there any advantage?

Expand full comment
dechichi's avatar

I use strcmp (I actually have my own string.h implementation, but it's same idea).

For a cmd line parser the number of strings to check is small and the length of each string is also small. In cases like this everything is very likely to be in a cache line which makes the search really fast even if it's O(n2).

I never tested a hash map implementation, but I suspect most implementations would *not* be faster, or if they were, only slightly faster. Worth a try though, let me know if you run the experiment!

Expand full comment
Rainbow Roxy's avatar

Thanks for writing this, it clarifies a lot. Absolutely agree.

Expand full comment