Hi, I'm new to Roc. I'm thinking about adding basic TCP listener functionality to the CLI platform. The implementation would basically mirror Rust's TcpListener with accept and bind functions which would return a stream which could be read and written to.
For this to work the Rust code would have to be able to return a Rust TcpListener and TcpStream to the Roc code. Is this possible and how would Rust's memory management track that memory?
Or is it better to have a dedicated TCP listener platform which follows more of the Elm approach?
I think some sort of web requests/TCP listener could be useful in the cli platform, but i am not fully sure how much we actually want to expand the cli platform/if we want to keep the version in the official roc repo more curated. I assuming adding more is mostly fine.
As for how it would be done. The most direct way would be to convert it to a pointer and pass the pointer to roc as an opaque type. Preferably pass it in a scoped way that takes a lambda such that you can free it once the lambda returns. Otherwise, it will have to be manually freed from the roc side. There may be some fancier tricks to help with handling lifetimes.
Also, if a platform should be dedicated or not mostly depends on scoping and if something can be standalone. If you want a cli app that can talk with TCP streams, you need both to be in the same platform. If you just want to talk with TCP streams, a TCP streams specific platform would make sense. Platforms really should be scoped for the expected use and sometimes even tailored to a specific roc app.
Passing a callback lambda to the host seems like a good approach. But do we have a good mechanism for the host to call it yet? How do we find out the byte size of the lambda set, etc.?
Also, my intention was just to do blocking calls, but is there a way to do non-blocking calls? i.e. neither Roc or Rust code is blocking. I couldn't see any callbacks in the examples.
Yes it is possible in general (though maybe not in an effect). That being said, to make this easy, I would just deal with the callback in the Roc api part of the platform. So you have create and destroy effects, but you don't expose those to the Roc app. The only thing you expose is a function that calls create, calls a callback, and then calls destroy.
Also, my intention was just to do blocking calls
I would definitely advise sticking with that for now. You can do async rust with roc, but it isn't nice and you have to do it in a special way.
Last updated: Jul 06 2025 at 12:14 UTC