4 ms·
I think it's underappreciated that Rust's `unsafe{}` doesn't exist in isolation. Rust has facilities for building safe abstractions on top of it, and has a cult
by pornel 3y ago
I think it's underappreciated that Rust's `unsafe{}` doesn't exist in isolation. Rust has facilities for building safe abstractions on top of it, and has a culture of taking this abstraction layer seriously.
Danger of unsafe features and FFI is usually conditional — you can use a pointer only until some point, or only on a single thread, etc. A use of unsafe in Rust doesn't become "be careful!" kryptonite spreading around the program. It's possible to build walls around it to contain it completely.
In Swift + unsafe or Java + JNI I've struggled building equally solid abstractions around FFI. They don't have "you can call it only once" or "you can't call go() after finish()" as a compile-time check. They don't have "you can use it only within this scope" (they may use a closure/callback to give access to an unsafe object, but these aren't hermetic, so that's a convention not a guarantee). Exposing objects to Swift or Java requires the higher level language to be in charge of their lifetime.
- mplewis9z 3y agoI haven’t had a chance to fully explore the new features and there are probably still some sharp edges, but the addition of non-copyable types and borrowing/consuming bindings in Swift 5.9 should bring it a lot closer to Rust in those respects, especially the hermeticity aspect. If you haven’t experimented recently, might be worth doing - this is also one of the big focuses of the language in the near term, so there should be lots more progress coming too.
- lmm 3y ago> They don't have "you can use it only within this scope" (they may use a closure/callback to give access to an unsafe object, but these aren't hermetic, so that's a convention not a guarantee). You can use the same trick as Haskell's STRef to prevent reusing a "leaked" unsafe object, although it's cumbersome enough in Java that you may not want to.
- mananaysiempre 3y agoThe ST monad trick requires second-order polymorphism, though [to type runST :: forall a. (forall s. ST s a) -> a]. Are any of those languages capable of it?
- lmm 3y agoJava certainly is; you might have to encode it as having your callback be an object with a (polymorphic) method, but for a long time that was something you had to do to express any callback in Java, so it's well-supported.
- deleted 3y ago[deleted]
- kaba0 3y agoJava’s recent Foreign Function & Memory API gives you temporal, spatial and thread-safety. In short, foreign memory is represented as a Segment, with known bounds (it also has a possibility for unbounded “pointers”, for e.g. c strings), associated to a scope. It can only be used within that scope, and will get automatically closed at the end of it.