3 ms·
> Would you consider `foo` a blue function and `bar` a red function? That doesn't seem particularly helpful to me. In the sense of effect/capability typing, I
by woodruffw 1y ago
> Would you consider `foo` a blue function and `bar` a red function? That doesn't seem particularly helpful to me.
In the sense of effect/capability typing, I think the answer is yes.
"Coloring" isn't magical, it's just a way to describe effects. Those effect can be described by keywords (`async` in JS, `throws` in Java, etc.) or special token parameters/types (what Zig does), but the consequences are the same: the effect propagates to the caller, and the caller becomes responsible for dealing with it.
- nextaccountic 1y agoYeah, parameter passing can be seen as some kind of effect (like the Reader monad in Haskell). Passing parameters down the call stack is viral just like function coloring (if you need to do i/o and thus need to receive an io parameter, then your caller must receive an io parameter too, recursively; this is analogous to adding a keyword async in front of your function, and to its callers recursively). The solution is probably some sort of implicit parameter, again, like the Reader monad. Note: async fn in Rust is also just a fn (in Rust's case, a fn that returns a future). It turns out that returning a future, or receiving as parameter a reference to the runtime, are equivalent in some sense
- koiueo 1y ago> Passing parameters down the call stack is viral It's in a different league comparing to async-await abomination. For one, you can store parameter on a struct thus working around the "virality" on a call site.
- 0x457 1y agoHuh? You have the following call stack (top to bottom): a -> b -> c -> d Function "d" does IO, so a, b and c need to pass that IO down. It's the same as with async in terms of virality. If I understood correctly, the main benefit here is that you don't have to dance around "can I call this function or is it going to block async runtime reactor?" I would pick async/await style over this because (I think) extra function argument is higher visual load than "async fn".
- koiueo 1y agoconst Greeter = struct { io: std.Io, pub fn greet(self: Greeter, msg: []const u8) !void { var stdout_writer = self.io.stdout.writer(); try stdout_writer.writeAll(msg); } } Greeter.greet("Look ma, no coloring")
- woodruffw 1y ago`greet` has Io within its closure, so I’m pretty sure this is consistent with the GP’s point.
- koiueo 1y agoIf you want to print a string from your function, you must supply it to the function. The fact that your function now receives `str: []u8` doesn't make it str-colored. On a side note: the entire "coloring" metaphor is extremely unfortunate and confusing IMO. It's somewhere at the top of my list (right beside the shroedinger's cat) of things which could've been explained better without dumbing them down.
- woodruffw 1y agoThat’s because str is not a meaningful effect, so we wouldn’t say that a function is “str-colored.” Function coloring is indeed confusing, which is why I’ve been trying to ground this on effects instead. Effects are IMO easier to understand, and this is a straightforward example of effect typing.
- 0x457 1y agoIf this is a special str that you have to pass down all the way through your call stack, then yes, it's str-colored.
- Rapzid 1y agoIt's also not true you can't call an async function from a sync function. In C# and JavaScript You can, you just can't "await" it. There are a lot of details involved, but it's just not true that you can't call async from sync.