Ted Kaminski

tedinski.com · Personal blog · on HN since 2018

Ted Kaminski writes essays on software design, abstraction, type systems and language design, including the expression problem and function coloring.

What HN saysHN commenters cite it for the expression problem and the wizard-versus-engineer divide, and one links its critique of SOLID principles.
52HN people shared it
11linked it in comments
50stories submitted
980story points
6 months agolast shared
2018people per year2026

Most-shared posts

  1. 1
    Programmer as wizard, programmer as engineer (2018)
    4 people · 168 points · first shared 2018 · 74 comments on HN
  2. 2
  3. 3
    Design duality and the expression problem (2018)
    4 people · 18 points · first shared 2018 · 8 comments on HN
  4. 4
    'Function Coloring'
    4 people · 7 points · first shared 2023 · discussion on HN
  5. 5
    How humans write programs
    3 people · 6 points · first shared 2018 · discussion on HN
  6. 6
  7. 7
    The one ring problem: abstraction and power (2018)
    3 people · 2 points · first shared 2021 · discussion on HN
  8. 8
    How did we end up with containers?
    2 people · 136 points · first shared 2018 · 74 comments on HN
  9. 9
    Backpressure (2019)
    2 people · 73 points · first shared 2021 · 17 comments on HN
  10. 10
    Fuzzing vs. Property Testing
    2 people · 64 points · first shared 2019 · 7 comments on HN
  11. 11
    Deconstructing the “Unix philosophy”
    2 people · 6 points · first shared 2018 · 1 comments on HN
  12. 12
    The end-to-end principle in distributed systems
    2 people · 5 points · first shared 2024 · discussion on HN
  13. 13
    Notes on the expression problem and type design (2018)
    2 people · 3 points · first shared 2024 · discussion on HN
  14. 14
    Testing at the Boundaries (2019)
    2 people · 2 points · first shared 2019 · discussion on HN
  15. 15
    What can we learn from how compilers are designed?
    1 people · 225 points · first shared 2018 · 84 comments on HN

What HN people wrote when they linked it

zogrodea · 2024-07-24
I had the same opinion with async/await, that it's nice to know a function performs IO and will wait before continuing. Makes it clearer when to use Promise.all to make multiple requests in parallel and wait for all of them to finish before continuing (faster than making calls sequentially). I kind of wish the languages I use had Haskell's IO monad too, to separate functions in terms of the type system, but that's slightly different. You might like this article (which is my personal favourite about function colouring). https://www.tedinski.com/2018/11/13/function-coloring.html
oxff · 2022-05-14
Writing a toy compiler, the entire pipeline end-to-end, for a language no matter how small. I can't think of another exercise that covers so many good issues to solve, and good practices for solving them. The two I like to recommend are: - PLAI: https://cs.brown.edu/courses/cs173/2012/book/ - Essentials of Compilation: https://wphomes.soic.indiana.edu/jsiek/ For general software design, this blog is quite golden: https://www.tedinski.com/archive/
chriswarbo · 2019-01-30
> It is quite well studied and solved in various languages I wouldn't say the expression problem is "solved"; various languages pick different tradeoffs, but the underlying problem is still there. The best description I've seen of this is at https://www.tedinski.com/2018/02/27/the-expression-problem.html
miki123211 · 2019-10-20
This is yet another example of the divide between wizarding and engineering[1]. When you're a small startup, what matters is the expressiveness of your language, and the ability do do a lot of things very very quickly. Type safety, performance, readability, those things don't matter. You're just a bunch of engineers who know the whole codebase inside out, you're pretty certain of what you're doing. In short, you're wizarding. If you grow big enough, this approach slows you down greatly, and you need to switch to engineering. You sacrifice some speed for making the codebase more understandable to a larger group of people, you can no longer assume everyone knows all the code, you write unit tests, need types and dislike metaprogramming because of the confusion it creates. This is why languages like Python, Ruby, Lisp or Smalltalk are amazing for small startups, but Java is what enterprises use. They're different ends of the wizarding/engineering spectrum. I wish there was a language that let you move gradually from one end to the other, exactly when you need to. [1] https://www.tedinski.com/2018/03/20/wizarding-vs-engineering.html
dzjkb · 2026-04-21
here's a nice critique of SOLID principles: https://www.tedinski.com/2019/04/02/solid-critique.html
gf000 · 2025-05-03
You need just the right amount of expressivity in a language, so that it is hard to abuse, but still allows writing easy to use libraries. Java has went over this evolution, implemented generics, lambdas, etc and I believe it strikes a very good balance in not being overly complex (just look at the spec - it's still a very small language, compared to its age, unlike C++ or C#). Go tried to re-invent this evolution, without having learnt Java's lessons. They will add more and more features until their "simple" will stop applying (though I personally believe that their simple was always just simplistic), simply because you need some expressivity for better libraries, which will later on actually simplify user code. Also relevant: https://www.tedinski.com/2018/01/30/the-one-ring-problem-abstraction-a…
ncruces · 2024-07-04
With the advent of coverage based fuzzing, and how well supported it is in Go, what am I missing from not using one of the property based testing libraries? https://www.tedinski.com/2018/12/11/fuzzing-and-property-testing.html Like, with the below fuzz test, and the corresponding invariant checks, isn't this all but equivalent to property tests? https://github.com/ncruces/aa/blob/505cbbf94973042cc7af4d6be6266454bb2… https://github.com/ncruces/aa/blob/505cbbf94973042cc7af4d6be6266454bb2…
svieira · 2023-06-05
See also: https://www.tedinski.com/2018/11/06/concurrency-models.html which is the first article I've ever seen that says that `m:n`-style-green-threads are bad and good at the same time. TL;DR - he says that "doParallel" and "doConcurrently" are separate operations with distinct semantics that designers of programs must care about and that conflating the two (especially the common "doConcurrently-and-often-but-not-always-in-parallel") is one of the most common causes of bugs in programs that need to make progress in multiple threads of execution.
ktpsns · 2023-01-16
I guess there is no easy answer for that. Here is an interesting blog post which resembles closely my opinion: https://www.tedinski.com/2018/11/13/function-coloring.html Edit: And of course there are alternatives such as Go or Zig: https://kristoff.it/blog/zig-colorblind-async-await/
matfil · 2019-02-01
The big one for me: how strongly do you equate "programming" with "engineering", and to what extent do you value other approaches (in the spirit of [1])? To what extent are ways of working circumscribed by tooling choices? "What are you selling?" (and is it something I can believe in) is pretty important too. [1] https://www.tedinski.com/2018/03/20/wizarding-vs-engineering.html
remexre · 2020-06-05
Sure, I mean more like there'd be some interface ByteStream, and probably another interface TerminalInput extends ByteStream; TerminalInput would then contain the especially terminal-related signals (e.g. sigwinch). If a program doesn't declare that it wants a full TerminalInput for stdin, the sigwinches would be dropped. If it declares it wants one but the environment can't provide one (e.g. stdin is closed, stdin is a file, etc.) it would be an error from execve(). Other signals would be provided by other resources, ofc; e.g. sigint should probably be present in all programs. --- In general, my ideal OS would have look something like [0], but with isolation between the objects (since they're now processes), provisions for state changes (so probably interfaces would look more like session types), and with a type system that supports algebraic data types. [0]: https://www.tedinski.com/2018/02/20/an-oo-language-without-inheritance…

Keyboard shortcuts

/Search
j kNext / previous blog
EnterOpen selected blog
vVisit the blog site
fFollow / unfollow
lSwitch grid / list view
dSwitch dark mode
g hHome
g pTop posts
g tTopics
g fFollowing
g lLiked
g yHistory
g qFAQ
EscBack / close