3 ms·
Nice! I’d imagine this is a much nicer experience than dialyzer. If the author is reading is it possible to type message passing / processes? I couldn’t see th
by akst 6y ago
Nice! I’d imagine this is a much nicer experience than dialyzer.
If the author is reading is it possible to type message passing / processes? I couldn’t see this in the docs but i may have missed it
- macintux 6y agoIt’s not. https://gleam.run/faqs.html#how-is-message-passing-typed https://gleam.run/faqs.html#how-is-message-passing-typed
- lpil 6y agoIt's not supported in the core language but we have some type safe bindings to messages and message passing as libraries. We may upgrade these to being part of the language itself but I don't want to rush this and get stuck with a sub-optimal design.
- mtarnovan 6y agoThis is a very interesting project, thanks. I'd love to see how you solve the problem of typed message passing in the language itself.
- lpil 6y agoThese two libraries are probably the best to look at: https://github.com/gleam-experiments/otp_agent https://github.com/gleam-experiments/otp_agent https://github.com/gleam-experiments/otp_process https://github.com/gleam-experiments/otp_process They could be improved but they are good enough for us to get started with.
- YorickPeterse 6y agoType safe process communication is a tough nut to crack. You can sort of handle it by doing away with PIDs or by at least making them generic, but that leaves out corner cases such as sending a message to the current process. Type inference of the message types is also hard, imagine something like this (using pseudo code here): let pid = spawn { ... hundreds of lines of code ... let message = receive message + 10 } ... lots of code here ... send(pid, 20) A compiler being able to infer the type of the message here will depend a bit on how it processes code: does it go into the spawn first, or process that later? If it does go into spawn first, what should it do when it reaches `message + 10`. And what if we were to process `send()` first, but it's actually sending the wrong type? We'd probably infer the type to be an integer, even if the receiving end actually wanted something else. Session types are one approach to dealing with this, but I have yet to see an implementation of this where it's actually pleasant to describe the session in the type system; most that I remember turn out horribly complex. I spent a fair bit of time on this for Inko (https://inko-lang.org/ https://inko-lang.org/) as it has a similar message sending system. Right now you'd have to use pattern matching to make things safe (this isn't released yet), but obviously I would like to check this at compile-time. Sadly I haven't been able to make this work yet, as there was always some corner case somewhere that meant that whatever I had implemented at that point wouldn't quite cut it. For a while Inko had a special API for this that basically worked by sending types closures to the receiving end, that way type-safety could be enforced by making sure the right closures were used. Sadly this is not the most efficient, and in some cases still required type annotations. One thing I did, but this may not work for Gleam, is to replace PIDs with just references to processes, and only allow obtaining such references by spawning a process. By not allowing one to just create a PID out of thin air, you reduce the likelihood of a process randomly receiving a message of a type it does not understand. A side benefit of this is not having to allocate PIDs, which I found out can actually be quite a bottleneck when spawning many processes (though Gleam being based on BEAM has no real choice in this matter).
- lpil 6y agoThanks for sharing your thoughts! It's quite reassuring to read your post as it sounds like we have had many of the same ideas about types and processes. > One thing I did, but this may not work for Gleam, is to replace PIDs with just references to processes, and only allow obtaining such references by spawning a process. This is my current plan, though it does make interop with Erlang/OTP somewhat more tricky. I'm going to have to redesign some of the behaviours there to make passing around references to processes possible.
- YorickPeterse 6y ago> This is my current plan, though it does make interop with Erlang/OTP somewhat more tricky. I have always wondered just how common it is in Erlang/Elixir to just fabricate a PID out of thin air and start sending messages to it. My gut feeling is that this is quite rare, but then again I'm not an Erlang user. If you want to rubberduck about anything related to this, feel free to send me a message/Email/Tweet/etc :)
- lpil 6y agoCreating the PID data structure is rare however it's common to give names to processes and then throughout the rest of the program make the assumption that there a process behind the given name that will handle the messages you are sending. I think we'll have to avoid this practice altogether.