H
Hirrolot
hirrolot.github.io · Personal blog · on HN since 2021
Hirrolot writes about programming language design, C metaprogramming, macros, Rust, and the complexity of static type systems.
What HN saysHN often cites his post on 'statics-dynamics biformity' to explain why static languages like TypeScript effectively become two languages.
27HN people shared it
11linked it in comments
20stories submitted
1.1Kstory points
12 months agolast shared
2021people per year2026
Most-shared posts
- 1Why static languages suffer from complexity8 people · 221 points · first shared 2022 · 290 comments on HN
- 2Rust Is Hard, Or: The Misery of Mainstream Programming5 people · 532 points · first shared 2022 · 795 comments on HN
- 3Why static languages suffer from complexity4 people · 5 points · first shared 2022 · 1 comments on HN
- 4Extend Your Language, Don’t Alter It3 people · 6 points · first shared 2021 · discussion on HN
- 5Macros on Steroids: How pure C can benefit from metaprogramming2 people · 92 points · first shared 2021 · 61 comments on HN
- 6What’s the Point of the C Preprocessor, Actually?2 people · 5 points · first shared 2021 · 3 comments on HN
- 7Pretty-Printable Enumerations in Pure C2 people · 3 points · first shared 2022 · discussion on HN
- 8Compiler Development: Rust or OCaml?2 people · 2 points · first shared 2023 · discussion on HN
- 9Solving SAT via Positive Supercompilation1 people · 153 points · first shared 2024 · 38 comments on HN
- 10Lolita: A tagless, dependently typed, self-aware programming language1 people · 32 points · first shared 2024 · 45 comments on HN
- 11Beatrice: A tagless, dependently typed, self-aware programming language1 people · 22 points · first shared 2024 · 2 comments on HN
- 12How to Keep Lambda Calculus Simple1 people · 2 points · first shared 2023 · discussion on HN
- 13Compiling algebraic data types in pure c991 people · first shared 2021
- 14Homepage1 people · first shared 2023
- 15Teloxide error1 people · first shared 2022
What HN people wrote when they linked it
lifthrasiir · 2023-09-30
There are also other approaches. Macro variants making use of `__VA_ARGS__` would be probably the best trade-off. If you want a slightly more ergonomic syntax, something like Metalang99 [1] will help (and the author even wrote a post about this exact subject [2]). Codegen is another option which may work better than other options depending on the situation and exact implementation strategy. And there is always the Reflection TS [3], which may or may not be incorporated to C++26...
[1] https://github.com/Hirrolot/metalang99
[2] https://hirrolot.github.io/posts/pretty-printable-enumerations-in-pure…
[3] https://en.cppreference.com/w/cpp/experimental/reflect
Hirrolot · 2023-03-02
> Inevitably, you will want to do something the framework did not forecast and will come up with convoluted ways to do it anyway.
I always find static site generators a kind of leaky abstraction. They eventually try to abstract nearly the whole functionality of the web stack, and the larger the SSG the more apparent it becomes. But, for obvious reasons, they just cannot abstract all the peculiarities of the web from you.
I write posts in Markdown, use Pandoc to convert `.md` to `.html` and a simple Go script in 200-300 LoC [1] for my https://hirrolot.github.io/.
[1] https://github.com/Hirrolot/hirrolot.github.io/blob/master/gen.go
samatman · 2022-11-05
I found this blog post on HN some time this year, and refer to it frequently:
https://hirrolot.github.io/posts/why-static-languages-suffer-from-comp…
The key thing the author identifies is the two languages problem. Static types are a second program about the program, and that's great when the second program is simple declarations that keep you from passing one struct when another is expected.
But a flexible language needs more than that, and generics end up either Turing Complete or bad in some other way.
I'll be mulling this one over in years to come.
throw10920 · 2022-09-21
> Expect<Equal<Hello, "World">>
This seems like a great time to bring up "Why Static Languages Suffer From Complexity"[1], which explains the "statics-dynamics biformity" that leads to languages like TypeScript that are actually two languages: the runtime one and the compile-time type-system one.
[1] https://hirrolot.github.io/posts/why-static-languages-suffer-from-comp…
brabel · 2022-02-02
This is called a "biformity". There was a great post about this the other day:
https://hirrolot.github.io/posts/why-static-languages-suffer-from-comp…
grose · 2022-06-19
I've been writing Go professionally for about 10 years now. I don't really buy your arguments against Go. Error handling is optional only if you explicitly ignore error results, and you can have the linter yell at you for that. The Go ecosystem is much larger and more mature, with many production-ready libraries available, and success stories everywhere you look. This article is a great illustration of how Rust just makes certain things hard, for better or worse: https://hirrolot.github.io/posts/rust-is-hard-or-the-misery-of-mainstr…
That being said, I think Rust is cool so I'll give you a hint. Go has a kryptonite: binary size. This didn't matter until recently when WASM runtimes became the new hotness. It is very very difficult to deploy Go on e.g. Cloudflare Workers. Even with Tinygo, it's a struggle getting your binary less than 1MB. Some features that make Go ergonomic like reflection (encoding/json package is a good example) ruin "tree-shaking" and bloat the binary.
If you're dead-set on using Rust, I'd try framing it in terms of edge computing. Rust is absolutely in a position to become the best non-JS language to use for these kind of 'workers' environments. And they have a lot of benefits: super fast, super cheap, effortless deploys, etc. so it's totally possible to make an argument for them. "Rust is the only compiled language viable in these environments"[1] is certainly a compelling position.
[1]. Hyperbole, I'm sure there's good progress…
skribanto · 2022-07-22
Rather than traits like what Rust has, the approaches I've generally seen for polymorphic behavior are explicit "interface" structs that hold a vtable, or comptime "duck-typing". I'm still rather new to Zig so there may be other approaches, but this is what I have seen so far.
One positive side effect is that there is only one "language" to learn as opposed to two different syntaxes like Rust does. While most people only use a very constrained part of the Rust type system, at the end of the day it is Turing Complete[1] (or possibly close to it? I don't know enough theory to know the rigor of what constitutes Turing completeness) and trying to keep all of it in mind can be taxing.[2]
[1]: https://sdleffler.github.io/RustTypeSystemTuringComplete/
[2]: https://hirrolot.github.io/posts/why-static-languages-suffer-from-comp…
lonk · 2022-06-11
Borrow checker is a good motivator
And rust is hard: https://hirrolot.github.io/posts/rust-is-hard-or-the-misery-of-mainstr…
rileyphone · 2022-04-13
https://hirrolot.github.io/posts/why-static-languages-suffer-from-comp…
Dynamic typing didn't come to dominate for no reason.
nyanpasu64 · 2022-07-09
Having used trait-based generics, I think that trying to piece together what's going on in typenum, the GAT stabilization process, https://hirrolot.github.io/posts/rust-is-hard-or-the-misery-of-mainstr… num-traits, and variance and https://github.com/rust-lang/rust/issues/25860 is absolutely bogging me down. I feel (and observe as people try modeling contracts in traits) that trying to build code which plays well with open-ended type parameters is inherently more difficult than building a correct solution for a single type. Generally I'd prefer a more focused less generic solution which corresponds to a single function in the generated machine code (modulo inlining), except in cases where generics (over a small or open set of types) provide a clear benefit (collections are a clear example, IMO point-free .iter().map().sum() style is usually a regression in readability).
estebank · 2022-06-03
> Rust even seems to provide you with the multi-page compile errors.
rustc strives to provide you as much relevant context as possible. When hitting very verbose output, it is a hint that what you're trying to do is difficult and will require considered design that the compiler can't help you with. The compiler is trying to help you clarify your code so that it can understand it.
Looking at the diagnostics shown in the blogpost, I see only one that is indeed terrible[1], but those in particularly are getting less and less verbose as we tackle them one by one with more targeted diagnostics. I also see the lifetime errors (the closure one when you specify the argument type and the on "`Execute` impl is not general enough"), which I wish gave more context.
As support for HRTBs lands, related errors will stop happening as much and the code will indeed work (or the compiler will be able to tell you what alternative syntax you should be using).
And, in a general plea for people writing Rust, when you encounter a subpar diagnostic, file a ticket[2].
[1]: https://hirrolot.github.io/media/rust-is-hard-or-the-misery-of-mainstr… Be aware that this is not exactly what rustc outputs, as some text decoration have been stripped, but that is a lot of text.
[2]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%…