[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)