salomonbrys
08/19/2019, 9:29 AMMarko Mitic
08/19/2019, 9:45 AMolonho
08/19/2019, 9:48 AMMarko Mitic
08/19/2019, 9:50 AMsalomonbrys
08/19/2019, 10:23 AMsalomonbrys
08/19/2019, 10:31 AMNabil
08/19/2019, 10:43 AMsalomonbrys
08/19/2019, 10:49 AMclass Foo(var bar: Int)
, the function fun mutate(val foo: Foo) { foo.bar = 42 }
could crash if foo
is frozen, and there is no way static analysis can know if it is. However, if const
was in the type system, we could have declare const class Foo
, which would have forbidden the use of var
in it (which renders the use of the freeze
API obsolete).darkmoon_uk
08/19/2019, 1:06 PMsalomonbrys
08/19/2019, 2:04 PMsalomonbrys
08/19/2019, 2:22 PMkpgalligan
08/19/2019, 2:40 PMkpgalligan
08/19/2019, 2:45 PMkpgalligan
08/19/2019, 2:46 PMkpgalligan
08/19/2019, 2:48 PMlouiscad
08/19/2019, 3:55 PMkpgalligan
08/19/2019, 3:58 PMshared
flag for a while, but itâs not public: https://github.com/JetBrains/kotlin-native/blob/1161e2c6b460002d7b854b032a6cfe07cae74df7/runtime/src/main/kotlin/kotlin/native/concurrent/MutableData.kt#L22). However, I was doing some more aggressive refactoring around Stately, but put that on the back burner until thereâs more clarity. Plenty of other things to work on.louiscad
08/19/2019, 4:10 PMconst
keyword idea, but I'm afraid it'd be seen everywhere and consequently adding significant noise. I though about the contrary: all classes const
by default, and a mutable
or var
modifier, but I think it'd be worse. Plus, what do you do with interface
or open
classes that could have mutable implementations/subclasses?
I am wondering if Rust code readers suffer from noise coming from concurrency constructs of the language and its stdlib⌠đ¤ (I almost don't know Rust)kpgalligan
08/19/2019, 4:22 PMconst
classes, except that to achieve the goal youâd only be able to âshareâ const
classes between threads. All other state would be permanently thread-confined. That would be significantly more confusing and frustrating than the current situation. If the idea is that const
is optional and all state can be shared, OK, but I fail to understand whatâs been solved. As for Rust-like language constructs, well, all for that if we could figure it out. Well, conceptually all for it anyway.louiscad
08/19/2019, 4:38 PMkpgalligan
08/19/2019, 4:46 PMkpgalligan
08/19/2019, 4:49 PMlouiscad
08/19/2019, 5:41 PMlouiscad
08/19/2019, 5:42 PMkpgalligan
08/19/2019, 6:02 PMAtomicReference
, what kind of errors?salomonbrys
08/19/2019, 7:04 PMconst
is not sufficient by itself. We also need a way to prevent non const static data.kpgalligan
08/19/2019, 7:34 PMvolatile
, which would I think be not great. Otherwise the compiler may decide the threadâs data is local and wonât be in a rush to make it available in main memory (among other issues)kpgalligan
08/19/2019, 7:35 PMsalomonbrys
08/19/2019, 7:36 PMkpgalligan
08/19/2019, 7:37 PMconst
, not the runtime?kpgalligan
08/19/2019, 7:39 PMsalomonbrys
08/19/2019, 7:54 PMlouiscad
08/19/2019, 8:06 PMvolatile
equivalent, which means increased performance for these objects.napperley
08/19/2019, 10:47 PMnapperley
08/19/2019, 10:57 PMnapperley
08/19/2019, 11:00 PMkpgalligan
08/19/2019, 11:02 PMnapperley
08/19/2019, 11:05 PMlouiscad
08/19/2019, 11:07 PMkpgalligan
08/19/2019, 11:13 PMkpgalligan
08/19/2019, 11:14 PMlouiscad
08/19/2019, 11:17 PMnapperley
08/19/2019, 11:20 PMdarkmoon_uk
08/19/2019, 11:23 PMpthread
API available on Posix native systems? Besides, of course, being back in an 'unsafe' place.louiscad
08/19/2019, 11:24 PMnapperley
08/19/2019, 11:25 PMkpgalligan
08/19/2019, 11:25 PMlouiscad
08/19/2019, 11:26 PMkpgalligan
08/19/2019, 11:26 PMkpgalligan
08/19/2019, 11:27 PMbasher
08/19/2019, 11:27 PMbasher
08/19/2019, 11:27 PMbasher
08/19/2019, 11:28 PMbasher
08/19/2019, 11:28 PMnapperley
08/19/2019, 11:31 PMlouiscad
08/19/2019, 11:31 PMlouiscad
08/19/2019, 11:34 PMbasher
08/19/2019, 11:38 PMlouiscad
08/20/2019, 1:35 PMForMutabilityException telling me the `AtomicReference`s themselves were frozen when I attempted to mutate their, what kind of errors?AtomicReference
value
var
member.kpgalligan
08/20/2019, 3:11 PMkpgalligan
08/20/2019, 3:11 PMimport kotlin.native.concurrent.AtomicReference
import kotlin.native.concurrent.freeze
class AtomicThingBox(t:Thing){
private val atom = AtomicReference(t.freeze())
init {
freeze()
}
var myThing:Thing
get() = atom.value
set(value) {
atom.value = value.freeze()
}
}
data class Thing(val s: String)
kpgalligan
08/20/2019, 3:14 PMval
for the AtomicReference
, the container may be frozen while init is happening and throw an error. Init order is vertical, AFAIK, so if you moved that init block to the top I think that would crash. Iâm not running these samples now, so will need to confirm later (one of those busy days)kpgalligan
08/20/2019, 3:15 PMinternal class FrozenDelegate<T>{
private val delegateReference = AtomicReference<T?>(null)
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = delegateReference.get()!!
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
delegateReference.set(value.freeze())
}
}
kpgalligan
08/20/2019, 3:15 PMvar sessionizeApi:SessionizeApi by ThreadLocalDelegate()
var analyticsApi: AnalyticsApi by FrozenDelegate()
var notificationsApi:NotificationsApi by FrozenDelegate()
kpgalligan
08/20/2019, 3:16 PMkpgalligan
08/20/2019, 3:17 PMThreadLocalDelegate
Is the counterpart to that. Whatever goes in there never leaves the thread you assigned it in, presumably the main thread.kpgalligan
08/20/2019, 3:18 PMlouiscad
08/20/2019, 3:20 PMfreeze
manually what went into the AtomicReference
, thanks for the info!
I'll reconsider what I reverted and test it in `object`s.kpgalligan
08/20/2019, 3:21 PMbasher
08/21/2019, 10:08 PMTop-level objects are frozen by default.This is only true for
object
(both object
and companion object
) vals. It's not true for globals. You have to mark them as @SharedImmutable
if you want that behavior.
Top-level variables are thread-local by default.That's not true. You have to mark them as
@ThreadLocal
if you want that behavior.Jeremy
08/25/2019, 12:27 AMlouiscad
09/11/2019, 8:07 PMFreezableAtomicReference
?kpgalligan
09/11/2019, 8:12 PMFreezableAtomicReference
. In theory itâs a good option. I think Iâve avoided it because I knew if the state was going to be frozen or not. FreezableAtomicReference
makes sense if you donât know the context in which the state will be used, but personally I try to be super clear on that.kpgalligan
09/11/2019, 8:12 PMlouiscad
09/12/2019, 8:26 AMimport kotlin.native.concurrent.FreezableAtomicReference
import kotlin.native.concurrent.freeze
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
internal class FrozenDelegate<T>(initialValue: T) : ReadWriteProperty<Any?, T> {
private val reference = FreezableAtomicReference<T>(initialValue.freeze())
init {
freeze()
}
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return reference.value
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
reference.value = value.freeze()
}
}
and I also freezed the whole object that uses these in its own init
block.
Works like a charm, thank you very much for the help Kevin!
Now, I'm wondering if I should always freeze what can be frozen. I assume yes, but please let me know if that's not the case.kpgalligan
09/12/2019, 1:25 PMinit
blockâ I think FreezableAtomicReference
does a couple extra checks internally on each access. Since youâre freezing anyway, thereâs no benefit to FreezableAtomicReference
. The extra checks arenât going to dramatically impact performance, but you should probably just use AtomicReference
in this case. If you donât freeze the FreezableAtomicReference
automatically, itâs a different situation.