Function Arguments Are Not Function Colors

ingve 42 points 29 comments September 08, 2026
jerf.org · View on Hacker News

Discussion Highlights (12 comments)

hoppp

Generally when talking about colored functions, I think of an example like "async function" in javascript, those are definitely different colored. I don't know about what would constitute as colored function in go as I generally don't consider arguments to be function colors. Maybe methods in go would be different colored functions when they are defined on different struct types.

kibwen

"Function colors" are just effect systems, which are not a new concept while also being extremely useful and super nifty. I hope someday we can stop wringing our hands in a panic over "colored functions" just because some ancient version of Javascript had a frustrating implementation of one specific effect. It reminds me of how ages ago certain people acquired an instinctual aversion to static typing attributable entirely to ancient versions of Java and its attendant verbosity and relative anemia.

kelseyfrog

A subset of function arguments are function colors because async/await is isomorphic to requiring and passing a `callback` arg around. It was named 'callback hell` because there wasn't an escape hatch and it affected every function in the callstack. I'd venture to guess that there's a more abstract way of formalizing this in the sense that monad instances are required to be threaded through the callstack in particular cases(would love to see this spelled out formally) where IO and Cont(?) have this requirement but State like the author points out, does not.

legobmw99

I think this is a fine distinction to make, though it's worth noting that function arguments _can be_ colors as the author describes if the arguments have to come from a specific place, e.g. in languages where only `main` receives certain arguments relating to system functionality, or a capability framework where only the top-level function receives the capability token.

skavi

Under this framework, Rust's async fns would not be colored, since any function in the callstack could be blocking on an executor. if you consider "spawn point" a part of the callstack, many other languages are similar. This doesn't feel like a useful distinction, but i don't think "function coloring" in general is a useful framework.

default-kramer

> What would it even look like for the top-most function to have to know “everything” that all the child functions end up ever needing? For every function parameter change in the entire program to somehow force a change all the way up the entire call stack? Clearly this does not happen. It so thoroughly does not happen that you may be having difficulty even imagining what it is I am talking about. Really? In my experience, it certainly does happen and I'm generally happy (but not thrilled) when it does. It means the type system is doing its job, forcing me to provide all the dependencies that a function needs. If 38 layers deep something now needs a connection string that it didn't have before, that had better bubble up to the top-most function. Unless of course the top-most function has already provided it to an intermediate layer which can break the chain, but that is very different than the context.Background() example.

smilekzs

My personal yardsticks: How often does a conceptually incremental change correspond to a proportionally incremental code diff, vs. a surprisingly whole-world-upside-down rearchitect? Do the code patterns naturally leave enough room for you to incrementally shift/transpose how things are organized? When the answers to these are unfavorable, I often find what effects to "coloring" in the framework, library, or language, sometimes all at once.

timando

Is `const`-ness (in the rust function keyword sense) a function color?

eikenberry

IMO it is a syntax thing. If you need to use a special keyword (eg. func vs async func) then it is colored. If it is a semantics thing (eg. parameters) is is not colored.

jongjong

>> JS... Because our strawman is a modern (shitty) language This is an attitude I dislike from all these niche language communities. They give each other pats on the back for shitting on the most popular, versatile, compatible and adaptable programming language of all time. I started using JS back in 2004 and, since then, I have watched it constantly being shat on by theoretically-minded folks. Before Node.js, people would keep pointing out "JS is a scripting language, not a programming language." Then, it became a programming language and went through the biggest adoption growth phase of any language in the history of mankind. I literally saw hardware manufacturers adopting JavaScript and even building custom JavaScript engines for their custom hardware, all while their academically-minded peers simultaneously shat on the language. They shat on it wave after wave, while it kept getting better and better and proved itself to be more adaptable than their own pet languages. People are so hard-headed and biased against JS that the community literally had to invent a new label/wrapper; 'TypeScript' as a Trojan horse to get those stubborn folks to use it. My view now is that JS critics are all talk. JS has been doing the walk; trampling all over their theories and abstractions and leading the way in many regards. Yes, it has bad parts, but all of these parts are avoidable; none of these parts are fundamental to the language. The matrix showing of how JS comparison operators down-cast everything to a string (leading to un-intuitive results) keeps being brought up but nobody asks the question "Why would anyone use a casting comparison operator to compare variables of two different types in the first place?". The fundamentals are excellent and proven as such.

mitxela

There's usually a way to run async on another thread (or this thread) and block on it, so async is not a color by your definition. I think color should be defined in terms of what you're likely going to do. You can call asyncio.run or context.Background or unsafePerformIO but they're both hacks that you shouldn't do because they are not correct, so we ignore them for colour analysis.

whateveracct

Actually, the IO monad in haskell desugars to RealWorld -> (a, RealWorld) Where RealWorld is a "token" that is just meant to be threaded through. You cannot create one yourself, so you have to be given one. Thus, that function argument colors IO. Every PL feature is just an extension to System F.

Semantic search powered by Rivestack pgvector
5,917 stories · 53,755 chunks indexed