In the pro-macro camp, if languages like JS had macros, the language could be kept much simpler, leaving things like pipeline operators, async / await, etc to developers.
In the anti-macro camp, they’re hard to write, reason about, and debug stack traces. They are also tempting to use when you shouldn’t, and I think a lot of software shops would run into trouble with them.
Regarding Clojure, I wouldn’t call Clojure a write-only language, but I did find that my Clojure code was more inscrutable than my code in other languages— roughly as inscrutable as my Haskell code. Something about it makes me want to code-golf my way into tiny little clever solutions.
Also, I’ve been burnt by various pitfalls of dynamically typed languages— upgrading dependencies in large dynamically typed projects, etc. I’ll take static types over macros any time.
Also, Clojure’s start up time was off-putting, and would probably be even more so today, coming from Bun and Go.
These days, most of my work is in TypeScript, and it’s just fine. Not perfect, but fine. I haven’t missed macros much.
All that said, I do like Clojure. I miss the baked in immutability, the ability to omit commas in arrays / lists / maps / etc, keywords, and the threading macros.
In summary, some of us have given it a shot, and ended up choosing a different path, and that’s ok.
> Also, Clojure’s start up time was off-putting, and would probably be even more so today, coming from Bun and Go.
Why is that? Never understood the complaint about slow Clojure startup time. Usually the context is either your local development environment, where you start the process once until you're done for the day, or you're deploying on a server and 5 seconds vs 10 seconds doesn't make that big of an impact. Short-lived CLIs aren't really suitable for Clojure in the first place, you'd use something like Babashka for that.
So why is the "slow startup" actually a problem? I don't seem to hit that issue ever myself, wondering what kind of situation people find themselves at where this hurts.
I also understand this is an issue for a lot of people but it’s never been an issue for me! I wouldn’t want it for serverless stuff I guess. But I would never think to do that lol
After 25 or so years doing this, I think there are two kinds of developers: craftsmen and practical “does it get the job done” types. I’m the former. The latter seem to be what makes the world go round.
I am both, I own a small agency when I have to be practical, and have fun crafting code on the hobby side.
I think what craftsmen miss is the different goals. Projects fall on a spectrum from long lived app that constantly evolve with a huge team working on it to not opened again after release. In the latter, like movie or music production (or most video games), only the end result matters, the how is not part of the final product. Working for years with designers and artists really gave me perspective on process vs end result and what matter.
That doesn’t mean the end result is messy or doesn’t have craftsmanship. Like if you call a general contractor or carpenter for a specific stuff, you care that the end result is well made, but if they tell you that they built a whole factory for your little custom made project (the equivalent of a nice codebase), not only it doesn’t matter for you but it’ll be wildly overpriced and delayed. In my agency that means the website is good looking and bug free after being built, no matter how messy is the temporary construction site.
In contrast if you work on a SaaS or a long lived project (e.g. an OS) the factory (the code) is the product.
So to me when people say they are into code craftsmanship I think they mean in reality they are more interested in factory building than end product crafting.
I also do third party software development, and my approach is always: bill (highly, $300+/hr) for the features and requirements, but do the manual refactoring and architecture/performance/detail work on your own time. It benefits you, it benefits the client, it benefits the relationship, and it handles the misunderstanding of your normie clients with regard to what constitutes "working".
Say it takes 2 hours to implement a feature, and another hour making it logically/architecturally correct. You bill $600 and eat $200 for goodwill and your own personal/organizational development. You're still making $200/hr and you never find yourself in meetings with normie clients about why refactoring, cohesiveness, or quality was necessary.
I agree wholeheartedly. As for the why do craftsmen care so much about the factory instead of the product, I believe the answer is pride. It’s a bitter pill to swallow, but writing and shipping a hack is sometimes the high road
If you've been doing it for that long (about as long as I have), then surely you remember all the times you had to clean up after the "git 'er done" types.
I'm not saying they don't have their place, but without us they would still be making the world go round. Only backwards.
I work in digital forensics and incident response. The “git ‘er done” software engineers have paid my mortgage and are putting my kids through private schooling.
> all the times you had to clean up after the "git 'er done" types
It’s lovely to have the time to do that. This time comes once the other type of engineer has shipped the product and turned the money flow on. Both types have their place.
I think there's more dimensions that also matter a bunch:
* a bad craftsman will get pedantic about the wrong things (e.g. SOLID/DRY as dogma) and will create architectures that will make development velocity plummet ("clever" code, deep inheritance chains, "magic" code with lots of reflection etc.)
* a bad practician will not care about long term maintainability either, or even correctness enough not to introduce a bunch of bad bugs or slop, even worse when they're subtle enough to ship but mess up your schema or something
So you can have both good and bad outcomes with either, just for slightly different reasons (caring about the wrong stuff vs not caring).
I think the sweet spot is to strive for code that is easy to read and understand, easy to change, and easy to eventually replace or throw out. Obviously performant enough but yadda yadda premature optimization, depends on the domain and so on...
After becoming a founder and having to deal with my own code for a decade, I’ve learned a balance. Prototype fast with AI crap to get the insight than write slow with structure for stuff that goes to production. AI does not touch production code - ask when needed to fix a tiny bit, but keep the beast at arms distance.
Yes. Maybe more so. The most famous lesson from that book is that you can’t just add bodies to a team and expect proportionate increases in productivity. I think vibe coding means more people simply makes the unmaintainability increase proportionate to the number of added people.
Yes. A small Surgical Team can Vibe Code a CRM today in a week.
The main problem with communication was Context.
What is your opinion on Context length with AI?
The problem Brooks describes around communication has to do with multiplying the number of paths as the team grows. The "surgical team" approach includes a member in charge of documentation at all stages, to give everyone access to the same context.
A small team may "vibe code" something they call a CRM in a week, but unlikely it will work and stand up to requirements changes. Only someone who doesn't understand the business domain would claim they can coax a solution out of an LLM in a few days.
RAM is a very cyclical market, historically. You can look at $MU historical charts and kind of see that it trades like a cyclical (compare it to $RIO, for example).
Cyclical companies are easily burned by investing in infrastructure right at the peak. It happens all the time with little mining companies, and I think DRAM manufacturers are sort of the mining companies of tech.
Cyclical markets are the sort of thing 'National Strategic Reserves' should address...
Am I crazy for wanting this to be in Full ECC RAM modules suitable for composition into many device factors with hope that we'll finally go to reliable memory for all markets as a result?
I’d love a way to be able to specify that sort of thing. I wrote a little server-side JSX rendering layer, and event handlers were serialized to strings, and so they had similar restrictions.
This looks great. If it works as well as the readme suggests, this’ll let me reach for Bun in some of the scenarios where I currently reach for Go. Typescript has become my favorite language, but the lack of efficient multithreading is sometimes a deal breaker.
I added a bit more information about Bun compatibility:
> While Bun is supported and Bun does support the `using` keyword, it's runtime automatically creates a polyfill for it whenever Function.toString() is called. This transpiled code relies on specific internal globals made available in the context where the function is serialized. Because the worker runs in a different isolated context where these globals are not registered, code with `using` will fail to execute.
In the anti-macro camp, they’re hard to write, reason about, and debug stack traces. They are also tempting to use when you shouldn’t, and I think a lot of software shops would run into trouble with them.
Regarding Clojure, I wouldn’t call Clojure a write-only language, but I did find that my Clojure code was more inscrutable than my code in other languages— roughly as inscrutable as my Haskell code. Something about it makes me want to code-golf my way into tiny little clever solutions.
Also, I’ve been burnt by various pitfalls of dynamically typed languages— upgrading dependencies in large dynamically typed projects, etc. I’ll take static types over macros any time.
Also, Clojure’s start up time was off-putting, and would probably be even more so today, coming from Bun and Go.
These days, most of my work is in TypeScript, and it’s just fine. Not perfect, but fine. I haven’t missed macros much.
All that said, I do like Clojure. I miss the baked in immutability, the ability to omit commas in arrays / lists / maps / etc, keywords, and the threading macros.
In summary, some of us have given it a shot, and ended up choosing a different path, and that’s ok.
reply