[HN Gopher] Swift-erlang-actor-system
___________________________________________________________________
Swift-erlang-actor-system
Author : todsacerdoti
Score : 182 points
Date : 2025-07-22 18:59 UTC (4 hours ago)
(HTM) web link (forums.swift.org)
(TXT) w3m dump (forums.swift.org)
| cyberax wrote:
| One thing for which I can't get a clear answer: Swift uses
| automatic reference counting. It seems that it needs atomic
| operations that are expensive.
|
| Does this allow somehow to sidestep this? Since the data is all
| thread-local, it should be possible to use non-atomic counters?
| dizlexic wrote:
| Never done it, but I hope this helps.
|
| https://stackoverflow.com/questions/25542416/swift-with-no-a...
| liuliu wrote:
| Only "class" object is reference counted (to some extents,
| class-like objects too). Int / struct (value-semantics) objects
| are not reference counted. These are copied eagerly.
|
| Swift introduced bunch of ownership keywords to help you to use
| value objects for most of the needs to sidestep reference-
| counting and minimize copying.
|
| Of course, to my understanding, "actor" in Swift is a
| "class"-like object, so it will be reference-counted. But I
| fail to see how that is different from other systems (as actor
| itself has to be mutable, hence, a reference object anyway).
| brandonasuncion wrote:
| And for times you need a fast heap-allocated type, Swift's
| Noncopyable types have been pretty great in my experience.
| Especially so for graph data structures, where previously
| retains/releases would be the biggest slowdown.
|
| Example here: https://forums.swift.org/t/noncopyable-
| generics-in-swift-a-c...
|
| An added plus is that the Swift compiler seems to stack-
| promote a lot more often, compared to class/ManagedBuffer
| implementations.
| llm_nerd wrote:
| The Swift compiler does lifetime and ownership analysis to
| eliminate many/most ARC overhead, beyond when things are truly
| shared between threads and the like.
|
| https://g.co/gemini/share/51670084cd0f - lame, but it
| references core concepts.
| cyberax wrote:
| I'm not sure how it can detect that outside of trivial cases.
| Any object that is passed into a library function can escape
| the current thread, unless the compiler can analyze all the
| binary at once.
| slavapestov wrote:
| > Any object that is passed into a library function can
| escape the current thread,
|
| In Swift 6 this is only true if the value's type is
| Sendable.
| llm_nerd wrote:
| Many (and increasingly most) Swift libraries are largely
| Swift modules delivered as SIL (Swift Intermediate
| Language). The compiler can indeed trace right into those
| calls and determine object lifetime and if it escapes. It
| is far more comprehensive than often presumed.
|
| Though the vast majority of cases where ARC would come into
| play are of the trivial variety.
| Someone wrote:
| In addition to what others said, even if counts have to be
| updated, that need not always use atomic operations.
|
| See https://dl.acm.org/doi/10.1145/3243176.3243195:
|
| _"BRC is based on the observation that most objects are only
| accessed by a single thread, which allows most RC operations to
| be performed non-atomically. BRC leverages this by biasing each
| object towards a specific thread, and keeping two counters for
| each object --- one updated by the owner thread and another
| updated by the other threads. This allows the owner thread to
| perform RC operations non-atomically, while the other threads
| update the second counter atomically."_
|
| (I don't know whether Swift uses this at the moment)
| carson-katri wrote:
| I worked on this project, thanks for sharing it! This is part of
| a larger otp-interop GitHub org with projects for things like
| running BEAM on mobile devices, disterl over WebSockets,
| filtering messages sent over disterl, etc. Happy to answer any
| questions about the project.
| __turbobrew__ wrote:
| I have read the erlang/OTP doesn't work well in high latency
| environments (for example on a mobile device), is that true?
| Are there special considerations for running OTP across a WAN?
| carson-katri wrote:
| In our use-case, we're running the client and server on the
| same device. But if you're connecting a mobile device to a
| "server" node, you would probably want to be careful how you
| link processes and avoid blocking on any calls to the client.
| bcardarella wrote:
| I hate to say this but usually when I hear that people have
| problems making Erlang/Elixir fast it comes down to a skill
| issue. Too often devs explore coming from another language
| and implement code as they would from that other language in
| Elixir and then see it's not performant. When we've dug into
| these issues we usually find misunderstandings on how to
| properly architect Elixir apps to avoid blocking and making
| as much use of distribution as possible.
| bcardarella wrote:
| I'm involved with this project and wanted to provide some
| context. This is an extraction for a much larger effort where
| we're building a web browser that can render native UI. Think
| instead of:
|
| `<div>Hello, world!!</div>`
|
| we can do:
|
| `<Text>Hello, world!</Text>`
|
| I want to be clear: this is not a web renderer. We are not
| rendering HTML. We're rendering actual native UI. So the above in
| SwiftUI becomes:
|
| `Text("Hello, world!")`
|
| And yes we support modifiers via a stylesheet system, events,
| custom view registration, and really everything that you would
| normally be doing it all in Swift.
|
| Where this library comes into play: the headless browser is being
| built in Elixir to run on device. We communicate with the SwiftUI
| renderer via disterl. We've built a virtual DOM where each node
| in the vDOM will have its own Erlang process. (I can get into
| process limit for DOMs if people want to) The Document will
| communicate the process directly to the corresponding SwiftUI
| view.
|
| We've taken this a step further by actually compiling client-side
| JS libs to WASM and running them in our headless browser and
| bridging back to Elixir with WasmEx. If this works we'll be able
| to bring the development ergonomics of the Web to every native
| platform that has a composable UI framework. So think of actual
| native targets for Hotwire, LiveWire, etc...
|
| We can currently build for nearly all SwiftUI targets: MacOS,
| iPhone, iPad, Apple Vision Pro, AppleTV. Watch is the odd duck
| out because it lacks on-device networking that we require for
| this library.
|
| This originally started as the LiveView Native project but due to
| some difficulties collaborating with the upstream project we've
| decided to broaden our scope.
|
| Swift's portability means we should be able to bring this to
| other languages as well.
|
| We're nearing the point of integration where we can benchmark and
| validate this effort.
|
| Happy to answer any questions!
| Jonovono wrote:
| Is there somewhere to follow this project? Sounds really
| interesting
| bcardarella wrote:
| * The working name of the browser is Crane:
| https://github.com/liveview-native/crane/tree/ios
|
| * our vDOM: https://github.com/liveview-native/gen_dom
|
| * selector parsing: https://github.com/liveview-
| native/selector
|
| * compile Elixir to ios: https://github.com/otp-
| interop/elixir_pack
| Jonovono wrote:
| Wow, unreal, thanks! I was playing around with Liveview
| native awhile back. Will definitely be following this along
| bratsche wrote:
| How does elixir_pack work? Is it bundling BEAM to run on
| iOS devices? Does Apple allow that?
|
| Years ago I worked at Xamarin, and our C# compiler compiled
| C# to native iOS code but there were some features that we
| could not support on iOS due to Apple's restrictions. Just
| curious if Apple still has those restrictions or if you're
| doing something different?
| bcardarella wrote:
| https://github.com/otp-interop/elixir_pack
|
| we compile without the JIT so we can satisfy the AppStore
| requirements
| victorbjorklund wrote:
| In what way will this be different from Liveview Native?
| bcardarella wrote:
| We're delivering LVN as I've promised the Elixir community
| this for years, from LVN's perspective nothing really
| changes. We hit real issues when trying to support live
| components and nested liveviews, if you were to look at the
| liveview.js client code those two features make significant
| use of the DOM API as they're doing significant tree
| manipulation. For the duration of this project we've been
| circling the drain on building a browser and about three
| months ago I decided that the just had to go all the way.
| ksec wrote:
| >If this works we'll be able to bring the development
| ergonomics of the Web to every native platform that has a
| composable UI framework.
|
| Holy this will be much bigger than I thought! Cant wait to see
| it out.
| aatd86 wrote:
| I believe swiftUI doesn't give access to the UI tree elements
| unlike UIkit. So I assume you're not allowing to use you xml
| like syntax to be in control of the UI? It's rather just an
| alternative to write swiftUI code? How do you handle state?
| Isomorphically to what is available in swiftUI? Is your VDOM an
| alternate syntax for an (Abstract) Syntax tree in fact? Is it
| to be used as an IR used to write swiftUI code differently?
|
| How is it different from Lynx? React Native? (probably is,
| besides the xml like syntax, again state management?)
|
| Quite interesting !
| bcardarella wrote:
| That's correct, but we can make changes to the views at
| runtime and these merge into the SwiftUI viewtree. That part
| has been working for years. As far as how we take the
| document and convert to SwiftUI views, there is no reflection
| in Swift or runtime eval. The solution is pretty simple:
| dictionary. We just have the tag name of an element mapped to
| the View struct. Same with modifiers.
| bcardarella wrote:
| As far as how it is different from React Native. That's a
| good question, one that I think is worth recognizing the
| irony which is that, as I understand it, without React
| Native our project probably wouldn't exist. From what I
| understand RN proved that composable UI was the desired UX
| even on native. Prior to RN we had UIKit and whatever
| Android had. RN came along and now we have SwiftUI and
| Jetpack Compose, both composable UI frameworks. We can
| represent any composable UI frameworks as a markup, not so
| much with the prior UI frameworks on native, at least not
| without defining our own abstraction above them.
|
| As far as the differentiator: backend. If you're sold on
| client-side development then I don't think our solution is
| for you. If however you value SSR and want a balnance
| between front end and backend that's our market. So for a
| Hotwire app you could have a Rails app deployed that can
| accept a "ACCEPT application/swiftui" and we can send the
| proper template to the client. Just like the browser we
| parse and build the DOM and insantiate the Views in the
| native client. There are already countless examples of SSR
| native apps in the AppStore. As long as we aren't shipping
| code it's OK, which we're not. Just markup that represents
| UI state. The state would be managed on the server.
|
| Another areas we differ is that we target the native UI
| framework, we don't have a unified UI framework. So you
| will need to know HTML - web, SwiftUI - iOS, Jetpack
| Compose - Android. This is necessary to establish the
| primitives that we can hopefully get to the point to build
| on top of to create a unified UI framework (or maybe
| someone solves that for us?)
|
| With our wasm compilation, we may even be able to compile
| React itself and have it emit native templates. No idea if
| that would work or not. The limits come when the JS library
| itself is enforcing HTML constraints that we don't observe,
| like case sensitive tag names and attributes.
|
| What about offline mode? Well for use cases that don't
| require it you're all set. We have lifecycle templates that
| ship on device for different app states, like being
| offline. If you want offline we have a concept that we
| haven't implemented yet. For Elixir we can just ship a
| version of the LV server on device that works locally then
| just does a datasync.
| rozap wrote:
| This is neat. I'm not a swift user, but I did work on a project
| where we made heavy use of JInterface (which ships in OTP), which
| is effectively the same thing but for JVM languages. It worked
| great and allowed easy reuse of a bunch of Java libraries we
| already had. Pretty painless interop model, imo.
___________________________________________________________________
(page generated 2025-07-22 23:00 UTC)