4 ms·
Swift-erlang-actor-system
- cyberax 1y agoOne 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 1y agoNever done it, but I hope this helps. https://stackoverflow.com/questions/25542416/swift-with-no-arc https://stackoverflow.com/questions/25542416/swift-with-no-a...
- liuliu 1y agoOnly "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 1y agoAnd 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-code-walkthrough/70862 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 1y agoThe 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 https://g.co/gemini/share/51670084cd0f - lame, but it references core concepts.
- cyberax 1y agoI'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 1y ago> 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 1y agoMany (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.
- elpakal 1y agousername checks out
- Someone 1y agoIn 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 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 1y agoI 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__ 1y agoI 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 1y agoIn 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 1y agoI 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.
- __turbobrew__ 1y agoOk, I just ask because I recently read the “BEAM book” and it explicitly calls out that OTP is designed to only run within a single datacenter.
- bcardarella 1y agoYou'd have to refer to all of the applications running on the BEAM that are distributed across multiple datacenters. Fly.io's entire business model is predicated on globally distributing your application using the BEAM. I'm not sure what that book said exactly perhaps the original intent was local distribution but Erlang has been around for over 30 years at this point. What it's evolved into today is architecturally unique compared to any other language stack and is built for global distribution with performance at scale.
- bcardarella 1y agoI'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 1y agoIs there somewhere to follow this project? Sounds really interesting
- bcardarella 1y ago* The working name of the browser is Crane: https://github.com/liveview-native/crane/tree/ios https://github.com/liveview-native/crane/tree/ios * our vDOM: https://github.com/liveview-native/gen_dom https://github.com/liveview-native/gen_dom * selector parsing: https://github.com/liveview-native/selector https://github.com/liveview-native/selector * compile Elixir to ios: https://github.com/otp-interop/elixir_pack https://github.com/otp-interop/elixir_pack
- rozap 1y agoThis 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.
- DeepYogurt 1y agoVery cool work.
- deleted 1y ago[deleted]
- nikolayasdf123 1y agoso can iOS devices (say iPhones) join Erlang actor cluster now? can someone explain?
- andy_ppp 1y agoThis is fantastic, you can write 99% of your system in Elixir and then if you need crazy performance you can write a GenServer in Swift that’ll give you near C/Go performance.
- innocentoldguy 1y agoElixir and Erlang outperform Go when under sustained load, so it may not be necessary to write a GenServer in Swift to achieve Go's performance. The top four areas where I've seen Elixir and Erlang outshine Go are concurrent workloads, memory management, fault-tolerance, and distributed systems.
- andy_ppp 1y agoIt depends what you are doing doesn't it. Maybe with Nx, Axon and EXLA most of the concerns are no longer an issue. However, there will always be some cases where doing things in lower level, mutable languages is faster.