Hm, not sure I’d agree. Software starts small sure, but as you say out of necessity, but that doesn’t make it minimalism–precisely because it’s a necessary step–until one makes the choice not to add to it. But I sense a danger of falling into an agile process discussion on this point so I’ll leave it there ![]()
Hello, I am opposed to python and my choice of elixir is for education and exploring ideas. My focus is on the logic of scaling. Please refrain from calling my decisions crazy, and bringing us off the theme of elixir by dropping a mess of python code into a discussion of a new crucial package.
My blog does more than static generation, and I display git codebases there also. While phoenix is a burden, I’m happy that I made some progress in elixir and plan to push further in this direction using Nex. If you begin to read my essays and code, you may see how I am lining up experiments for programs and machine deployments.
Ah, sorry for that. I didn’t mean that in a disparaging way. Maybe “overkill” or something would be a more appropriate word to articulate my meaning than “crazy”? In any case, I apologize for offending you. If the goal is to learn/experiment, then by all means use whatever technologies interest you. I’m all for that! ![]()
The Python code was just an example of how to build a static website manually because I had it lying around (it’s the real code that builds my blog and the static FE/doc site for a public API I run). The same thing could be done with .exs scripts in Elixir, and Elixir would probably be a better fit for that particular script actually since it is component-based. Basically, it just looks for <!– modulr-component: component-name –> comments in html pages and replaces them with the HTML in a src/components/component-name.html file. Works well for reuse between articles/pages without any runtime cost in the built site. Elixir is great for that kind of processing due to it’s pipeline syntax and concurrency primitives. I wrote a CLI tool to do language-agnostic find-replace (like sed but without making my brain hurt) across an entire project in Elixir and it’s lovely. I use it for e2e renames at work all the time. ![]()
I will say that I can understand if you find Python off-putting. A lot of people do, but it’s a very useful language to know since it’s the most convenient glue/automation language out there. I think all devs should know a bit of Python and JS (even though I hate JS) since they are so ubiquitous. ![]()
I also wouldn’t say that Phoenix is a burden. It just comes with a lot of extra stuff that most blogs wouldn’t need, which is why I mentioned static site generation.
Cheers!
Great to see an alternative to Phoenix based on convention-over-configuration. I rather like that paradigm for the same reasons Elixir has a rigid build-in formatter.
A ‘support it all’ framework is nice to have but will always need to expand when the use base growth (so the relative amount of features use decreases). Having a fixed set based on a philosophy and resisting the urge to please everyone, keeping the mental modal small, will be a selling point imho.
For that you might turn to Routex - build powerful Phoenix routes: localize, customize, and innovate
One thing that I am watching with curiosity in all such similar threads is the seemingly inevitable intent of the community to deconstruct a bigger framework like Phoenix to its constituent parts and make sure they all can work together and it then becomes an exercise of “assemble your own framework”. F.ex. you might have multiple ways to do routing and static file serving.
And this concept is already kind of in place with mix phx.gen.auth where you generate it and then customize it to your liking.
While that does somewhat sound intuitively nice to have, I am not sure how maintainable it will be in reality.
I’ve spoken against one particular aspect of Phoenix in the past: too many files. Outside of that though, it does seem to do what it needs to do fairly well. Very curious about alternative frameworks like Nex and how they fit!
This is a big problem with the JS ecosystem. JS devs are spoiled for choice with npm libs, but they end up needing to write so much glue code to make incompatible libraries work together that they might as well just build it themselves.
One of the things I love about Elixir is that it doesn’t suffer from this nearly as much. Most of the time, I don’t feel like I need to reach for a library at all since the standard lib is very rich, but when I do, the library usually fits together with regular standard lib code very well because of common patterns like OTP/supervision and pipeline-based apis.
Oh, absolutely. My ideal such architecture would be N choices that implement the same set of API (guess we could call them protocols in Elixir parlance) and people would choose based on various merit.
But I know: what color do I like my dragon?
It is a curse to fell into the dependency hell. Someone I respect deeply even went all the way to claim package managers are evil.
There was a quote attributed to our own José:
In real life, when you have a dependency, you are responsible for it
In software, many people have the opposite idea that one can offload responsibility by adding a dependency.
Yeah, I like to think of using an open source library the same as hiring an independent contractor. I’m relying on them for some crucial part of my business/application, so I should treat it that way (and pay them if it’s feasible).
In practice, it’s difficult to actually use the classic c-style vendor-deps approach, but it’s not impossible. The godot engine does it in their codebase due to license incompatibilities and problems with dynamic linking when cross-compiling for different release platforms. It’s a lot of work to maintain vendored deps, but it works, and I’ve never had godot fail to compile from source due to some missing binary on my laptop. ![]()
What’s the idea behind these articles, exactly?
Most good devs on this planet understand the problems. But nobody is willing to fund a true change of the status quo.
I suppose it was therapeutic for the author to write it because there would be zero other positive effects on the world coming from the fact that one more such article got written.
GingerBill is the creator of Odin, which is a manifest of all of his philosophy, including not providing a package manager and actively encouraging user to vendor 3rd party libraries. So he walks his walks.
He does deserve respect for sticking to his guns, absolutely, though my point was that by itself does not contribute to anything positive out there. Odin might be even more niche than Elixir.
Still, you don’t need to respect my opinion on this as it’s just that – an opinion. I am simply more open to people and software that actively try to repair the fairly broken state of the bigger IT area.
One example would be: GitHub - x-motemen/ghq: Remote repository management made easy.
A lot of us have to manage multiple softwares and other artifacts by cloning and keeping up to date stuff from Git. A program like that adds some convenience and removes the need for everyone to roll their own bespoke mini-manager.
Neovim’s Lazy and Mason package / plugin managers are other good examples. They make a convention and follow it and only present you with what you care about.
But man, vendoring dependencies? Nope. Though if you find me an employer who would be willing to accept a status update of the sort “I have been installing and upgrading our project’s dependencies for the last two weeks” and they are OK with it then I might reconsider. ![]()
Odin provides official vendoring of many libraries:
Given that it’s niche language for video game development, I think it is pretty impressive. I am skeptical for a general solution across many languages though. It will be yet another tool to learn that handles some easy task well and leaves the hard part alone or make it even harder.
I share that skepticism, sadly. But yes, if a tool can be invented that does language-agnostic dependency management, that would be a nice game-breaker for a lot of ecosystems.
Language-agnostic dependency management would be cool. I would imagine it would be really hard to do without running into all the problems things like npm have but at an even larger scale. Probably something like the immutable deps in unison would be the most feasible approach. I haven’t looked at it in a while, but IIUC, unison hashes every code artifact, so deps are automatically managed kind of like checking out specific git commits. Seems cool for distributed computing.
The immutable deps idea is cool. If I ever get free time, I might try experimenting with that in Elixir. I would even be willing to try it in unison if their website had about 97% fewer emojis and their code examples used snake_case instead of camelCase. ![]()
- Namespace are non-negotiable, akin to every Git hosting. You can’t have a global namespace and that’s that. Also adding optional private repos like Hex is doing it (either for company-managed and vetted deps or just for paid stuff like Oban Pro) would also help a lot.
- Hashing everything a la the Unison lang is indeed absolutely inevitable. Supply chain vulnerabilities have been around for decades but various bad actors finally woke up and started exploiting them just in the last few years (really says something about their IQ though
). - Relevant article that I aim to reread once a month: https://guix.gnu.org/en/blog/2024/identifying-software/
- Additionally to Unison-like hashing: let us start hashing the damned AST itself already! No need to break hundreds of hashes because Joe the new dev in the team figured he’ll reformat the entire code base with the new and trendy formatter. Though hashing AST comes with a big exciting pile of problems i.e. ABI stability which is something that Rust still does not have – but it’s IMO stable enough. And same for Erlang / Elixir; but again, it’s good enough.
Okay grandpa, let’s put you to bed. ![]()
I started becoming indifferent to the whole stuff of snake_case and camelCase and others.
Between auto-completion and asking your LLM agent to generate you the next 20 lines, who cares really. But I’ll admit that with time I learned to very quickly scan through them and that’s truly very helpful.
lol. I enjoy being a curmudgeon about things like camelCase. It’s one of those things that’s mostly pointless, but people still get super passionate about for some reason. What I’ve observed is that people tend to prefer the convention in their first language. I did talk to someone recently who preferred camelCase because he said it made him feel more like a programmer. I asked him his reasoning, and he said it’s unique to the programming vernacular and not something that is used in other fields whereas most other naming conventions can be found in other fields. I thought that was an interesting take.
For my part, I actually do have a single practical reason for disliking camelCase beyond the simple fact that my first language was gd script which uses snake case: It’s hard to parse.
My preferred naming convention these days is snake_case for identifiers and hyphenated-words for files. This makes code gen super easy since it’s very easy to convert an identifier to a filepath and vice/versa and also differentiate them programmatically. The only downside is that international applications can bite you if you try to split on the hyphen character from a US ascii keyboard, but that’s not hard to work around. There are a limited number of hyphen-like characters in the unicode set. On the other hand, camelCase requires splitting on capitals, which has a much larger set of possible delimiting characters even in plain ascii, but especially in international applications (looking at you uppercase dotted i), which makes things more difficult when parsing strings char-by-char in something like C. There also isn’t a convenient built-in string parsing helper for splitting up camelCase words in most high level languages, but even Javascript with its non-existent standard lib has a split method on strings that usually works for parsing snaked and hyphenated strings into words… usually.
The only high level language I’ve ever used that doesn’t have an adequate split function for strings built-in is Lua.
But that’s all just me justifying my aesthetic preferences. ![]()
Got to be honest here, choosing one or the other on the basis of whether it can be programmatically (or with CLI tools) parsed easily would be my very last concern – if it ever would occur to me at all.
I see the both sides. While I do enjoy snake_case because to me it is objectively easier to eyeball visually, I’m also periodically doing small hobbyist work with Golang and you know what? You just get used to it.
It’s not really a blocker, it’s only a matter of habit.
You are quite self-aware that you are doing post-hoc rationalization, and I appreciate you for it. We all do it.
To me this became one of the “us vs. them” tiring tropes that plagues every group of this dumb race. We all have so much more in common than we think.
I agree with you. I’m currently in the unfortunate position that most of us find ourselves in of having to write lots of JS code at work, so camelCase is the predominant naming convention in most of the code I get paid to work in. I also find snake_case easier to read, but I can read camelCase just fine as well after working with it for years. Same with curly braces vs indentation for block scoping. I would argue indentation is more readable and we use it in natural written language as well, but curly braces are fine once the brain learns to associate them with the semantics of scope, and I know at least one programmer that started with curly brace languages and never used whitespace languages and he had a really hard time differentiating scope in Python code cause his brain had been trained to look for curly braces.
I’ve only recently gotten on board with hyphens for filenames though. I recently wrote a data migration tool at work that does code gen similar to something like ecto.gen.migration but also allows selecting migrations to run via a CLI menu. The easy conversion from hyphen to snake made the whole thing a lot simpler to implement since I only had a day to build the prototype. Startups are nuts. lol
But that is also mostly just post-hoc rationalization ofc. There are plenty of ways to build that kind of thing. I think I just find the way that the code, file tree, and CLI display all fit together with those conventions aesthetically pleasing.






















