Live data from Hacker News

Zig's new I/O: function coloring is inevitable?

blog.ivnj.org

71–80 of 83 posts

Re: Zig's new I/O: function coloring is inevitable?

#71
post #19

Earlier quoted context omitted.

So its impossible to get an allocator through a different means from inside a function? It must be passed in?

No, it's entirely possible. And that's why we don't think about "has an allocator" as a colouring problem. Likewise if JavaScript had an easy way to get a handle to its Runtime, and a function "block on promise" in its early days, we'd have never had all these "colouring" arguments.

If javascript worked differently we wouldn't have arguments about that significant feature of javascript.

How would you add "block on promise"? Javascript started off without the ability to block on anything, not even I/O because it didn't have I/O. Later when XMLHttpRequeest was added it was purely callback-based.

There are ways to make that API work but introducing the concept of blocking would be a big language change. It's not fixing a flaw, it's trading away some complications for a different pile of complications. There's still a conflict to resolve in language design when you want some functions that are synchronous and don't block and other functions that are asynchronous.

Edit: I guess javascript blocks on alert() but that doesn't seem like what you'd want "block on promise" to do...

Re: Zig's new I/O: function coloring is inevitable?

#72

Earlier quoted context omitted.

The vtable example is nonviral.

I don’t see how that can be the case, given that Io is in the closure. Anything that wants to do I/O needs that token; that’s what virality is.

I think I almost agree with what I think you mean, but I'm not sure, hopefully you'll entertain a few questions?

Say you have two functions one that does some kind of IO, (say a pair of bidirectional read, write, from stdin and stdout) and another that returns a block of memory of a constant size. Would you say that one is colored, and the other isn't?

I'll also try to make an attempt at the idea I'm trying to figure out too. I genuinely can't predict which side you'll answer for, but I'm assuming you'll say that it's not colored, because while it does do IO, but only directly though the global file descriptors which have no baring on the calling conventions. Which means the decisions and impact about which color this IO function doesn't ever apply to the callers and callees. This I think is the virality you mean where the callers and callees are required to know [something] about the semantics? I probably agree you could call this coloring and defend it... It's interesting that this might be closer to the "accepted" definitions of what any language means when it says this function is colored. But I don't think this understanding most people have about the concept of coloring. Most I see are arguing about the semantic effects, much more than the "accepted" definition. I have the distinct impression that when most say coloring, the most significant implication is when and where you resolve the specific color. Will it be sync or async code, when, where, and who gets to decide.

Or perhaps I'm wrong, and you would say that one function is colored, but the other isnt? Then I'd ask if you can tell it's colored, can you tell me which color?

In both cases I'd argue it's better to embrace the semantic widening of the concept of function coloring, because what I understand from how you describe it, I feel that saying this is coloring is strictly less enlightening about the reality of the code and system together, than calling this function alpha. With zig's new IO interface, I can't tell you what the RGB values are for the color, but I can confidently say, it's alpha channel is 0xff. You might not be able to tell me what color it is, but it without a doubt isn't a pure function, interacts with IO and does have a null byte in the alpha channel.

Re: Zig's new I/O: function coloring is inevitable?

#73

Earlier quoted context omitted.

No, it's entirely possible. And that's why we don't think about "has an allocator" as a colouring problem. Likewise if JavaScript had an easy way to get a handle to its Runtime, and a function "block on promise" in its early days, we'd have never had all these "colouring" arguments.

If javascript worked differently we wouldn't have arguments about that significant feature of javascript. How would you add "block on promise"? Javascript started off without the ability to block on anything, not even I/O because it didn't have I/O. Later when XMLHttpRequeest was added it was purely callback-based. There are ways to make that API work but introducing the concept of blocking would be a big language ch…

JavaScript is (notionally) "single threaded", you can block with just a busy loop; that's not a language change. It's bad design to block, which I expect is what you mean, but that's not a language problem.

If you did so in a Worker, you'd have your "don't block the UI thread" in there too.

Re: Zig's new I/O: function coloring is inevitable?

#74

Earlier quoted context omitted.

If javascript worked differently we wouldn't have arguments about that significant feature of javascript. How would you add "block on promise"? Javascript started off without the ability to block on anything, not even I/O because it didn't have I/O. Later when XMLHttpRequeest was added it was purely callback-based. There are ways to make that API work but introducing the concept of blocking would be a big language ch…

JavaScript is (notionally) "single threaded", you can block with just a busy loop; that's not a language change. It's bad design to block, which I expect is what you mean, but that's not a language problem. If you did so in a Worker, you'd have your "don't block the UI thread" in there too.

If you busy loop waiting for something in javascript, your program dies. They're not just a bad idea, they're a non-option.

Blocking in the sense of blocking I/O or blocking on a system call is not possible in javascript. So again I ask what you have in mind for a "block on promise" call. The ideas that come to my mind all require significant redesigns of the execution model, or copping out by making every function async and treating it like an await.

In particular with workers in mind, I'll put it this way: If you don't allow "block on promise" in the main thread, you generally avoid these issues, but you also don't solve the problem, you still have async versus not async causing many headaches. If you do allow it on the main thread, how do you keep your page functioning? I can imagine resolutions but they all have severe compromises.

Re: Zig's new I/O: function coloring is inevitable?

#75

Earlier quoted context omitted.

JavaScript is (notionally) "single threaded", you can block with just a busy loop; that's not a language change. It's bad design to block, which I expect is what you mean, but that's not a language problem. If you did so in a Worker, you'd have your "don't block the UI thread" in there too.

If you busy loop waiting for something in javascript, your program dies. They're not just a bad idea, they're a non-option. Blocking in the sense of blocking I/O or blocking on a system call is not possible in javascript. So again I ask what you have in mind for a "block on promise" call. The ideas that come to my mind all require significant redesigns of the execution model, or copping out by making every function a…

Every time you call a JS function, it's blocking; if it internally busy-looped, you'll die just as much as if you do the loop yourself.

Being able to block on an async function call is just as much of a risk; if it returns quick, you live, if it returns slow, you die.

The solution to "main page unresponsive, terminate page?" is to always return promptly to the Runtime, so e.g. make everything async. But JavaScript is a language, and it doesn't just exist on web page main threads. As much as JS's proliferation everywhere else isn't my cup of tea, a blocking call in a JS cli tool is what you want.

EDIT: I guess to be explicit:

> So again I ask what you have in mind for a "block on promise" call

I expect it to have the same guarantees and risks of calling a non-async JS function.

Re: Zig's new I/O: function coloring is inevitable?

#76

Earlier quoted context omitted.

If you busy loop waiting for something in javascript, your program dies. They're not just a bad idea, they're a non-option. Blocking in the sense of blocking I/O or blocking on a system call is not possible in javascript. So again I ask what you have in mind for a "block on promise" call. The ideas that come to my mind all require significant redesigns of the execution model, or copping out by making every function a…

Every time you call a JS function, it's blocking; if it internally busy-looped, you'll die just as much as if you do the loop yourself. Being able to block on an async function call is just as much of a risk; if it returns quick, you live, if it returns slow, you die. The solution to "main page unresponsive, terminate page?" is to always return promptly to the Runtime, so e.g. make everything async. But JavaScript is…

> Every time you call a JS function, it's blocking; if it internally busy-looped, you'll die just as much as if you do the loop yourself.

But in a very temporary way. If it takes seconds that's a bug, while if blocking I/O takes seconds that's normal behavior.

And I've never seen a javascript busy loop in non-malicious code.

> I expect it to have the same guarantees and risks of calling a non-async JS function.

The main guarantee is that the function will be done and have all its temporary data cleaned up before your (non-worker) execution switches to other code. And in practice you can expect it to return within .1 seconds.

That guarantee is going to be an issue if you try to introduce some kind of "block on promise". And the timing expectation is meaningful too.

Re: Zig's new I/O: function coloring is inevitable?

#77

Earlier quoted context omitted.

> async/await contexts are not first-class values Because async/await are not values, they are ways to run/structure your code. That's why they are so infectious. If you don't want the division the only solution is to make everything of one kind. Languages like C make everything sync/blocking, while languages like Go make everything async.

> Because async/await are not values They are computations that produce values. Computations can be reified as values. What do you think functions and threads are? As I described above, "delimited continuations" are values that subsume async/await and many other kinds of effects. You can handle async/await like any other value if they were reified as delimited continuations, but this makes the compiler writer's life…

> As I described above, "delimited continuations" are values that subsume async/await and many other kinds of effects.

Supporting delimited continuations force some specific ways of performing computations. They are akin to making everything async, which proves my point: you have to make everything of one kind in order to solve the problem.

Re: Zig's new I/O: function coloring is inevitable?

#78

Earlier quoted context omitted.

> Because async/await are not values They are computations that produce values. Computations can be reified as values. What do you think functions and threads are? As I described above, "delimited continuations" are values that subsume async/await and many other kinds of effects. You can handle async/await like any other value if they were reified as delimited continuations, but this makes the compiler writer's life…

> As I described above, "delimited continuations" are values that subsume async/await and many other kinds of effects. Supporting delimited continuations force some specific ways of performing computations. They are akin to making everything async, which proves my point: you have to make everything of one kind in order to solve the problem.

> They are akin to making everything async, which proves my point: you have to make everything of one kind in order to solve the problem.

You can use ordinary direct style compilation, but all references to stack values simply have to be relative offsets, then a simple implementation of shift/reset is just capturing context and copying stack fragments, which you can do using setjmp/longjmp in C (although there are better ways [1]).

This is not akin to making everything async, nor is everything "of one kind", whatever that means. A delimited continuation is very much its own kind of thing, distinct from other values, and doesn't have to influence the function call/return semantics unless you're targeting a less flexible runtime like the JVM.

[1] https://github.com/koka-lang/libhandle

Re: Zig's new I/O: function coloring is inevitable?

#79

Earlier quoted context omitted.

> As I described above, "delimited continuations" are values that subsume async/await and many other kinds of effects. Supporting delimited continuations force some specific ways of performing computations. They are akin to making everything async, which proves my point: you have to make everything of one kind in order to solve the problem.

> They are akin to making everything async, which proves my point: you have to make everything of one kind in order to solve the problem. You can use ordinary direct style compilation, but all references to stack values simply have to be relative offsets, then a simple implementation of shift/reset is just capturing context and copying stack fragments, which you can do using setjmp/longjmp in C (although there are be…

> but all references to stack values simply have to be relative offsets

Then such references are no longer pointers, and in order to have a generic reference (that can point to both stack memory and heap memory) you have to store additional data (which one of them it points to) and conditionally use the correct one any time you access it. This is a very invasive change to the memory model.

> then a simple implementation of shift/reset is just capturing context and copying stack fragments, which you can do using setjmp/longjmp in C

That sounds like you're just reinventing green threads then, which basically forces everything to be async once you start noticing its issues.

> https://github.com/koka-lang/libhandle

This returns a 404 error for me.

> This is not akin to making everything async, nor is everything "of one kind", whatever that means.

Sure, if everything has to be able to "wait" for the result of a continuation then you're forcing async support on everything.

If instead you implement continuations as some kind of monads that users have to return from their functions then you got function coloring because you can't normally wait for the result of a continuation from a function that does not return a continuation.

Re: Zig's new I/O: function coloring is inevitable?

#80
post #51

Earlier quoted context omitted.

`greet` has Io within its closure, so I’m pretty sure this is consistent with the GP’s point.

If 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.

If this is a special str that you have to pass down all the way through your call stack, then yes, it's str-colored.
Post reply on HN