21 ms·
Always with the blooming red and blue functions. You can say exactly the same thing about const. The fact that a function can perform asynchronous operations m
by omnicognate 3y ago
Always with the blooming red and blue functions. You can say exactly the same thing about const.
The fact that a function can perform asynchronous operations matters to me and I want it reflected in the type system. I want to design my system on such a way that the asynchronous parts are kept where they belong, and I want the type system's help in doing that. "May perform asynchronous operations" is a property a calling function inherits from its callee and it is correctly modelled as such. I don't want to call functions that I don't know this about.
Now you can make an argument that you don't want to design your code this way and that's great if you have another way to think about it all that leads to code that can be maintained and reasoned about equally well (or more so). But calling the classes of functions red and blue and pretending the distinction has no more meaning than that is not such an argument. It's empty nonsense.
"We" don't all agree on this.
- randyrand 3y agoMaybe a better example is returning errors, than const. Either way, all of these changes are really annoying to make. We want less of these annoyances, not more.
- assbuttbuttass 3y ago> The fact that a function can perform asynchronous operations matters to me and I want it reflected in the type system. async doesn't tell you whether the function performs asynchronous operations, despite the name. async is an implementation detail about how the function must be invoked. As TFA correctly points out, there's nothing stopping you from calling a blocking function inside a future, and blocking the whole runtime thread.
- omnicognate 3y agoI didn't say it tells me whether the function does perform such operations, I said it tells me it can. More importantly it tells me which functions (most) can't.
- anonymoushn 3y agoIt would be swell if functions could be generic over this capability at compile time, so that you could get the same guarantees from the type system without implementing the same protocols more than one time.
- bobbylarrybobby 3y agoKeyword generics!
- logicchains 3y agoHaskell supports this, but right from the start Rust was always wary of trying to add higher kinded types, which are necessary to support this.
- anonymoushn 3y agoAs a Zig programmer I also get to enjoy this, but from the angle of language implementors not caring about type theory
- hgomersall 3y agoWe do not want functions that take floating point arguments, only u32 should be used. And don't get me started on more than one argument!
- randyrand 3y agoyou can convert a float to a u32. you cannot convert an function that calls async code into a sync function.
- kevingadd 3y agoYou can call .Wait on the Task it returns :)
- randyrand 3y agoRight, but now you are forced to convert the calling function to async. u32 / float does not have the problem. It does not "bubble up", unless you want it to.
- kprotty 3y agono, .Wait in C# or block_on in Rust keep the caller sync while evaluating the async callee, preventing the "bubble up".
- hgomersall 3y agoAn async function is some syntactic sugar around a sync function that returns a future. You can merrily call one from the other. You can only convert an int to a float with significant caveats. It's not a general trivial conversion. More complicated types may not be convertible at all or behave in all sorts of exciting ways (including having arbitrary side effects). The point is that none of that is different to async functions. Of course you have to know what to do with them for them to be useful, but there is no requirement for them to "infect" calling code.