How could BEAM VM benefit a desktop app?

Curious: Can you think of any desktop apps where having Beam VM would be beneficial?

1 Like

Generally, outside of the state of libraries for desktop in elixir world, most I would say. Fault-tolerance and seamless concurrency, especially when it comes to the UI thread that in most application freezes from even to this day, are amazing features to have.

Obviously embedding the entire runtime is a huge thing to ask for a native application, but I think nowadays we got beyond this point (NVIDIA driver updates have 500MB, like goddamn, BEAM runtime takes about 30MB for reference).

2 Likes

The desktop UI elements being different entities and you sending messages to each of them lends itself excellently to the BEAM VM’s model. It’s a natural fit.

2 Likes

These days I’m doing a large amount of Qt development (again, sigh) and I couldn’t agree more.

… makes me wonder what happened with Scenic… not exactly the same as a Qt type framework, but it was definitely a move in that direction.

Scenic is oriented for embedded UIs use-cases such as kiosks. It can be used as a base framework, but you would still need to build a lot of functionality to get it even close to something like qt.

1 Like

Interestingly (maybe?) there was a PoC project that allowed one to run a QtQuick / QML gui with logic in a BEAM language. The idea was to have messages from the “business logic” in the BEAM bridged over into the QtQuick runtime, and vice versa so that bound events from the QtQuick runtime (keep in mind that changing values of bound variables are, from a mental model perspective, events themselves) could appear as messages in the BEAM code.

This bridging actually worked fairly well, with it feeling relatively “native” on both ends. It never went beyond PoC as a curiosity, but it did demonstrate the plausibility of this approach. It would mean not requiring a U/X library written in e.g. Elixir while keeping all the business logic there … with all the benefits and interesting possibilities of both worlds being available.

I do think this would provide a lot of interesting possibilities, including:

  • a sharp separation of business logic from UI
  • painless multi-threaded business logic for desktop apps
  • painless recovery from errors in business logic (which is such a pain in desktop apps)
  • a very easy pathway to network services, allowing easier integration of online services with desktop applications
  • inter-application communication between apps via message passing, which could be done via local sockets or by simply tying all the desktop apps together into a local BEAM cluster. Both would require some thought as to safety (stability, security, …), but would be within reach.

Besides having the resilience of the BEAM as wlel as the pleasure of writing functional code with an OO UI, I believe it would allow for patterns that are currently hard to achieve, such as transparent movement of application state between machines (including application code itself), interaction across the network without requiring intermediate web services (at most a reflector service, which itself could be a simple BEAM application) …

There are a lot of possibilities here. Should desktop innovation become a useful area of interest again at some point, this is one of the ideas I have sitting around waiting to be dusted off :slight_smile:

5 Likes

I’d love to see Elixir be well usable for desktop development, but that’s only because I like Elixir while I am not doing much of desktop dev, so easy development ways would let me create apps for desktop without much learning.

However, I guess making elixir (or any other BEAM language) well usable for desktop needs some bigger motivation than that :slight_smile:
To be honest I don’t see much overlap between desktop UI communities and elixir communities and thus not much is happening in the area. It can certainly change whenever some desktop-minded people (or companies) who love Elixir/BEAM appear, but who knows how it can happen.

Meanwhile IMHO best chances for elixir are about enabling people who already love and use elixir for the web services be able to use same web techniques (and especially LiveView) for rapid desktop development - sort’a Electron way.

P.S.
Yes, I never mention any BEAM capabilities, because IMHO all the BEAM reliability isn’t really a big benefit for the desktop development - sure it’s useful if you want to build bulletproof apps that scale easily, but there are not really desktop app cases IMHO. LiveView and easy UI updates are, BEAM features - only in the amount that supports LiveView.

1 Like

I’ve looked into this a bit and from what I can see this is what we’ve got: either you’ve got a NIF that’s driving the UI (like we do with wx) or you’ve got an outside program running your BEAM and talking to the BEAM over a socket (like ElixirKit or Liveview Native)

Both have their benefits and drawbacks. I wouldn’t say that there is a clear “winner” at the moment, it depends on what you’re trying to do.

I’ve had some fun with wx (and OpenGL) but it’s not as portable as you might think, and requires much dickering to get it to work right. Having a native app running the BEAM as a subprocess might be the optimal solution, but there remains a lot of work to get that right too.

2 Likes

Speaking as someone that does a substantial amount of desktop development, I have to disagree with this point of view. Concurrency, not resiliency, is probably the bigger story of what the BEAM has to offer desktop development. This isn’t to say that resiliency is a minor concern in user facing desktop applications, but concurrency can color all the user interactions and not just the badly behaving ones.

If we look at common desktop development paradigms, meaning GUI event driven programming, we typically have some assemblage of “widgets” which sit there waiting for an interaction. The nature of the interaction can vary… so, for example, a user may check/uncheck a checkbox widget setting it, or I may set it programmatically, or either case could set it to a tertiary state. Such an action will change some internal state in the widget object itself, but also typically result in signaling other interested parts of the application that the interaction took place, perhaps along with the resulting state. The other parts of the application which received that signal may themselves change the state of the other widgets in the UI, internal state, or even programmatically change the original checkbox state, all of which can cascade into another whole set of signals and signal responses… etc. until some bottoming out condition is reached.

These widgets sitting around with independent state and independently waiting for a user interaction, and the internal state related logic of the form, again waiting for interesting signals to decide what to do, sounds an awful lot like agents sending and receiving messages. Sure an event loop looks and feels more like Pub/Sub to a GUI developer, but in the end the notion that you have some program sending messages to none or more interested other programs feels like BEAM processes sending messages to each other.

And good, well considered concurrency can very much influence the user’s experience of an application. The snappiness and responsiveness of a user interface can depend heavily on if widgets and display elements can send their signals and move on while other parts of the program process as instructed by responding to those signals: stop-the-world interactions are often times negatively felt by users. This isn’t to say you can be careless and the concurrency is a cure all: it’s a necessarily element, though not sufficient on its own.

Resiliency can be also important in a GUI, too. I work with ERP systems and the one in which I deal with that uses Qt/C++/JavaScript is a good example. I often times find end users with their desktop client open and a dozen or more independent forms open: may a couple items are up, the customer, a sales order, current stock levels, etc. They do this because they need to research, they were in the middle of task 1 and urgent task 2 came up, etc. It is conceivable, particularly when dealing with data tables in the UI for example, to take a reference to a row in the table, refresh the table (meaning all the row objects are destroyed and new ones are created), and then try to operate on the just deleted row object. In the C++ this usually crashes the application meaning that all the forms the user had open crash, including ones which might have incomplete work product or that they simply spend the time to open for whatever they were trying to accomplish: in the end it’s a pretty crappy user experience. Now, with BEAM like resilience the bigger likelihood is that the task referencing the now deleted row just finishes (no shared mutable state), but in the worst case the widget crashes, or even the form crashes, but the whole application doesn’t need to crash. Sure there are ways to fix this in Qt/C++ and ways to screw it up with the BEAM… the real question between the two is how easy and in which direction does the development environment push you?

Finally, I should caveat this saying while I think at a shallow level of analysis the BEAM seems like it would be compelling to build a desktop framework around, it’s not clear that the details support that conclusion. Maybe the way the BEAM implements scheduling or the serial nature of a single processes message passing make it inappropriate to drive the event loop, etc of such a framework. I haven’t done that analysis, but it seems like something that technically would be reasonable to investigate.

In the end I don’t think we’ll see any progress along these lines. GUI frameworks are a big lift and I just don’t see enough momentum in the community to push that direction. I don’t think the obstacles are technical or that the BEAM has nothing to offer desktop development. I think the biggest barriers are sociological and demand driven.

7 Likes

I think Smalltalk now represented by Pharo offers a good example of what the might look like in terms of architecture and capabilities.

Elixir with the BEAM is already very similar to Smalltalk/Pharo. The big difference is Pharo includes a native desktop UI library AND a native IDE which uses the native UI. This native IDE does the Elixir equivalent of module hot swapping.

But we are in a different age now where desktop can mean a web based interface like Eclipse. Like VSCode. Does anyone write true desktop apps anymore?

1 Like

Except being slow. All the message serialization and de-serialization would make message passing slower than OOP style dynamic method dispatch. No mainstream GUI framework is implemented using the actor model for a reason.

I don’t disagree but this is mostly a fixable problem. Doesn’t have to be Elixir per se. Have you seen how insanely fast Rust channels are, for example? You can send 20000 messages and the user would not have started blinking yet.

If speed/efficiency is not a concern then it might be simpler to give up on the whole idea of having GUI widgets with a life cycle, and go with a full immediate mode style of GUI programming. Many games are done this way.

It’s weird that with all the speed ups in tech we get all this GPU stuff still happens to be a huge leaky abstraction in so far that it even leaks into decisions about programming paradime. I recently watched https://www.youtube.com/watch?v=TAQ7yBLRZ3U which was quite an interesting talk on that topic by someone having built a react like system for GPU rendering.

1 Like

This subject makes me think of BeOS. Granted, it never was mainstream, however, it was using an actor model on 90’s hardware. It was quite impressive for its resilience and concurrency. I didn’t know BEAM at the time, but now I see huge parallels. I’m sure Erlang was an inspiration.

2 Likes

Really? Did it use green threads with per-thread heaps, like Erlang? I thought it was using some kind of co-routine backed by c macros.

Now that you ask for the details, I’m not certain. I was a novice programmer working in interpreted languages at the time. I bought a PowerPC Mac Clone and could dual boot classic MacOS and BeOS. I read articles about the BeOS architecture, and firsthand experienced how much it could do with the same hardware than MacOS could.

1 Like

Just for completness: SymbianOS (and of course EPOC before that) used in their applications an actor model.

Btw. Another approach I was thinking is the Electron (nodejs + browser) approach. Elixir could use phoenix, liveview + browser. On nerves there are attempts with the kiosk approach

1 Like

From what I can see here:

Seems to be implemented with green threads sharing a heap. Every window is a separate thread running its own run loop waiting for messages. So, it is using the actor model on the per-window level, not on a per-widget level. Very neat.

2 Likes

I find this a very baffling topic in that, on the one hand I have written responsive (in the old “responds quickly” sense rather than responsive web page sense) GUIs on computers with only 1MB of RAM and a 16 MHz i386. Smalltalk also had a very responsive GUI for this platform. I think one could definitely implement a responsive BEAM based GUI for a modern machine. It should even be possible with a lowly SBC.

The baffling part is again, why would you want to? Apple has amazingly well thought out, easy to use desktop GUI libraries that have been tested and improved for 40 years. They started life as NextStep and were based on Smalltalk. Meanwhile, Linux desktops have yet to become popular. It might be interesting for an SBC. But there is already Phoenix.

I understand it’s frequently the things where everyone goes “why would you do that” which “surprisingly” become really successful. I like the concept. But I am blind to the value.

Now, what about the BEAM on GPUs?? Not ML but the actual BEAM? And able to use the separate GPU cores for separate processes just like a multi-core CPU? Sort of like k8s but the fabric is the GPU cores.?

1 Like