5 ms·
The greatest power of BEAM-based languages is the fully preemptive actor model. Nobody else supports it. This is a superpower, the solution of most problems wit
by atemerev 2y ago
The greatest power of BEAM-based languages is the fully preemptive actor model. Nobody else supports it. This is a superpower, the solution of most problems with concurrent programming.
In Erland and Elixir, actors and actor-based concurrency hold the central place in the corresponding ecosystems, well supported by extensive documentation.
In Gleam, actors and OTP are an afterthought. They are there somewhere, but underdocumented and abandoned.
- vereis 2y agoGleam runs on the BEAM
- atemerev 2y agoIt does. However, its actor implementation is not built upon Erlang/OTP, and currently is “experimental” and not even mentioned on the main site.
- lolinder 2y ago> its actor implementation is not built upon Erlang/OTP This seems to be the opposite of pragmatic. The most pragmatic approach to actors when you're building a BEAM language would be to write bindings for OTP and be done with it. This sounds kind of like building a JVM language with no intention of providing interop with the JVM ecosystem—yeah, the VM is good, but the ecosystem is what we're actually there for. If you're building a BEAM language, why would you attempt to reimplement OTP?
- arcanemachiner 2y agoI believe their implementation was written to support static typing (since Gleam is a statically-typed language).
- okkdev 2y agoBecause of type safety. The OTP lib is already great, but there are still some things missing, most requested being named processes. But there is work being done to figure out how to best make it work for gleam.
- lolinder 2y agoThe question of type safety has come up so often here that I guess it's worth replying: That's exactly what I mean by this not seeming pragmatic. Pragmatic would be making do with partial type safety in order to be fully compatible with OTP. That's the much-maligned TypeScript approach, and it worked for TypeScript because it was pragmatic. Now, maybe Gleam feels the need to take this approach because Elixir is already planning on filling the pragmatic gradually-typed BEAM language niche. That's fine if so!
- okkdev 2y agoType safety is one of the goals of the language I don't see a reason to throw it out of the window now. I see what you mean, but the type system is one of the things that makes gleam pragmatic. If you really need some missing OTP feature you can super easily step into Erlang using FFI and get it. That's one of the reasons the article doesn't call gleam pure.
- lpil 2y agoGleam does not sacrifice OTP compatibility for type safety. It picks both.
- giraffe_lady 2y agoAnd what has this approach gotten them? A language as complex as c++ and haskell combined, but that still has runtime type errors. A typescript backlash is coming.
- H12 2y agoIIRC the re-implementation was necessary for type-safety.
- pmontra 2y agoI agree with the part about reusing OTP but some of the server syntax of Erlang and Elixir is not good IMHO. I never liked using those handle_* functions. Give them proper names and you cover nearly all the normal usage, which is mutating the internal state of a process (an object in other families of languages.) That would be the pragmatic choice, to lure Java, C++ programmers.
- throwawaymaths 2y agoElixir gives you Agent, which is what you want, but for reasons, Agent is a bad choice. What you're not seeing with the handle_* functions is all the extra stuff in there that deals with, for example, "what if the thing you want to access is unavailable?". That's not really something that for example go is able to handle so easily.
- toast0 2y agoWhat would be the proper name to handle a call other than handle_call?
- pmontra 2y agoThis is Elixir syntax, not Gleam: Instead of defmodule Robot do def handle_call(:get_state, _from, state) do something() end def get_state() do GenServer.call(__MODULE__, :get_state) end end robot = Robot.start_link() robot.get_state() just let me write (note the new flavor of def) defstatefulmodule Robot do def get_state() do something() end end robot = Robot.new() robot.get_state() Possibly add a defsync / defasync flavor of function definition to declare when the caller has to wait for the result of the function. The idea is that I don't have to do the job of the compiler. It should add the boilerplate during the compilation to BEAM bytecode. I know that there are a number of other possible cases that the handle_* functions can accommodate and this code does not, but this object-oriented-style state management is the purpose of almost all the occurrences of GenServers in the code bases I saw. Unfortunately it's littered by handle_* boilerplate that hides the purpose of the code and as all code, adds bugs by itself. So: add handle_* to BEAM languages for maximum control but also add a dumbed down version that's all we need almost anytime.
- deleted 2y ago[deleted]
- lpil 2y agoIt uses the same primitives as Erlang, the difference is that it exposes type safe APIs instead of untyped ones which you would get from using the Erlang abstractions. It implements the same protocols and does not have any interop shortcomings.
- lpil 2y agoIt is production ready and has been used for numerous non-trivial projects. Experimental in this context means there is expected to be API changes and feature additions in future.
- steve_adams_86 2y agoThis is exactly what I want from Gleam. It does seem to be under documented and abandoned. Is there any understanding of why? Like you say, this seems like a super power. I see so much potential. A language that’s ergonomic, pragmatic as the author says, great performance, low-ish barrier to entry, etc. It seems like it could be an awesome tool for building highly reliable software that’s not so difficult to maintain.
- cassepipe 2y agoIt is a very young language that may explain the why
- lpil 2y agoIt is not abandoned, I am the maintainer. The documentation covers the APIs of the package but not the “zen” of the wider OTP framework, for that the official OTP documentation and existing books are recommended.
- atemerev 2y agoOK, thanks! I will try to write something with it and perhaps come help with the documentation.
- steve_adams_86 2y agoThat’s great information, thanks. I seem to recall checking the commit history and it didn’t seem dead, but I’m also accustomed to experimental packages being dropped early and often. Do you want help with maintenance or are you doing this independently?
- lpil 2y agoContributions are very much welcome! Gleam is entirely a community project.
- steve_adams_86 2y ago
- jatins 2y agothis is Gleam OTP package https://github.com/gleam-lang/otp https://github.com/gleam-lang/otp I agree it's underdocumented but doesn't seem abandoned (has commits in last week)
- dullcrisp 2y agoI understand things best by comparing across different languages so don’t take this the wrong way but I wonder if you can help me understand: If say I start a goroutine in Go and give it a channel to use as a mailbox, concurrency in Go is cooperative but it’ll automatically use OS threads and yield whenever it reads from the channel. Does Erlang/OTP do something different? If so what does it do and what are the advantages? Or is it more that the library and ecosystem are built around this model?
- throwawaymaths 2y agoI believe go yields after every function exit. Erlang does the same, but there are no loops (you must use tailcall) so you can't lock up the CPU with a while(true).
- samatman 2y agoThat used to be true, but no longer, goroutines are truly preëmptive, in 10ms time slices.
- throwawaymaths 2y agoThanks!
- Jtsummers 2y agoErlang gives a reductions budget to processes. After a certain number of reductions, or if a process hits a yield point (like waiting to receive a message), the process will yield allowing another process to run. Go uses preemption now (since 1.14), but it didn't always. It used to be that you could use a busy loop and that goroutine would never yield. Yield points include things like function entries, syscalls, and a few other points.
- sodapopcan 2y agoAre there any articles that do a deeper dive into this? I ask because straight up I've been curious about Gleam, but not enough to do a really deep dive because Elixir is too good and, like Erlang, is a very special kind of dynamic language that doesn't leave me feel too lacking. As I understand it, there have been a few "high profile" attempts to bring static typing to Erlang, all of which gave up when it came to typing messages. Your comment essentially confirms my bias, but is Gleam making real strides in solving this, or is it poised to merely cater to those who demand static-typing with curly braces--everything-else-be-dammed?
- sodapopcan 2y agoSorry, the end of my comment is quite reductive. Compiling to JS is pretty nice.
- lpil 2y agoHello! I’m the maintainer of the Gleam OTP library. It is not abandoned or an afterthought.
- vfclists 2y agoDon't be so modest!! You are the creator of the Gleam language as well.
- atemerev 2y agoHi! Good to hear. Why it is not mentioned anywhere on the main site?
- lpil 2y agoIt is referenced in multiple places on the main site. The home page has a code snippet from it, though it does not go into any detail about any specific library.