Nir
07/16/2020, 3:58 PMTobias Berger
07/16/2020, 4:51 PMNir
07/16/2020, 5:19 PMNir
07/16/2020, 5:19 PMNir
07/16/2020, 5:20 PMNir
07/16/2020, 5:20 PMNir
07/16/2020, 5:21 PMTobias Berger
07/16/2020, 5:22 PMNir
07/16/2020, 5:22 PMNir
07/16/2020, 5:22 PMTobias Berger
07/16/2020, 5:23 PMNir
07/16/2020, 5:23 PMNir
07/16/2020, 5:23 PMTobias Berger
07/16/2020, 5:25 PMNir
07/16/2020, 5:25 PMNir
07/16/2020, 5:25 PMNir
07/16/2020, 5:25 PMNir
07/16/2020, 5:26 PMNir
07/16/2020, 5:26 PMNir
07/16/2020, 5:28 PMTobias Berger
07/16/2020, 5:28 PMNir
07/16/2020, 5:29 PMNir
07/16/2020, 5:29 PMNir
07/16/2020, 5:29 PMNir
07/16/2020, 5:29 PMNir
07/16/2020, 5:30 PMNir
07/16/2020, 5:30 PMNir
07/16/2020, 5:31 PMNir
07/16/2020, 5:31 PMFleshgrinder
07/16/2020, 7:14 PMFleshgrinder
07/16/2020, 7:15 PMNir
07/16/2020, 7:18 PMNir
07/16/2020, 7:19 PMNir
07/16/2020, 7:19 PMNir
07/16/2020, 7:20 PMNir
07/16/2020, 7:20 PMNir
07/16/2020, 7:22 PMNir
07/16/2020, 7:23 PMinline class foo(val x: Int) : Int by x
gives me a pile of errors basicallyFleshgrinder
07/16/2020, 7:25 PMobject
works.Nir
07/16/2020, 7:25 PMNir
07/16/2020, 7:26 PMclass foo(val x: Int) : Int by x
does not work eitherFleshgrinder
07/16/2020, 7:30 PMInt
isn't an interface, hence, it cannot work. Number
would. Gimme a sec, I'll prepare an example.
In Rust terms: you are trying to impl i32 for foo
which isn't possible there either.Fleshgrinder
07/16/2020, 7:33 PMFleshgrinder
07/16/2020, 7:33 PMC
is from a different library.Nir
07/16/2020, 7:34 PMNir
07/16/2020, 7:34 PMFleshgrinder
07/16/2020, 7:34 PMNir
07/16/2020, 7:35 PMFleshgrinder
07/16/2020, 7:35 PMNumber
is an abstract class but that's close enough I'd say (since you CAN extend it).Nir
07/16/2020, 7:35 PMNir
07/16/2020, 7:36 PMsealed class JsonData {
class IntWrapper(val x: Int) : JsonData()
class StringWrapper(val x: String) : JsonData()
class ListWrapper(val x: JsonArray) : JsonData()
class ObjectWrapper(val x: JsonObject) : JsonData()
class NullWrapper() : JsonData()
}
Fleshgrinder
07/16/2020, 7:36 PMInt
to Number
works but not String
to Number
.Nir
07/16/2020, 7:36 PMJsonValue
with a member var jsonData: JsonData
Nir
07/16/2020, 7:37 PMclass glug(val x: Int) : Number by x
Nir
07/16/2020, 7:37 PMNir
07/16/2020, 7:37 PMNir
07/16/2020, 7:37 PMNir
07/16/2020, 7:37 PMFleshgrinder
07/16/2020, 7:38 PMNir
07/16/2020, 7:38 PMFleshgrinder
07/16/2020, 7:38 PMNir
07/16/2020, 7:38 PMNir
07/16/2020, 7:38 PMNir
07/16/2020, 7:38 PMcompanion object {
fun make(x: Int): JsonValue {
val j = JsonValue()
j.jsonData = JsonData.IntWrapper(x)
return j
}
fun make(x: String): JsonValue {
val j = JsonValue()
j.jsonData = JsonData.StringWrapper(x)
return j
}
inline fun <reified T> make(x: List<T>): JsonValue {
val j = JsonValue()
j.jsonData = JsonData.ListWrapper(x.map { JsonValue.make(it) })
return j
}
}
Nir
07/16/2020, 7:38 PMNir
07/16/2020, 7:39 PMmake
function to work for List<Int>
, List<String>
, and so onNir
07/16/2020, 7:39 PMFleshgrinder
07/16/2020, 7:39 PMNir
07/16/2020, 7:39 PMNir
07/16/2020, 7:39 PMNir
07/16/2020, 7:40 PMNir
07/16/2020, 7:40 PMmake
function doesn't call itself recursively then it's not going to work in the ideal wayNir
07/16/2020, 7:41 PMNir
07/16/2020, 7:41 PMmake
to properly work, including recursively, for built in typesNir
07/16/2020, 7:41 PMNir
07/16/2020, 7:42 PMmake
Nir
07/16/2020, 7:42 PMNir
07/16/2020, 7:42 PMfun make(data: Any?): JsonValue {
val j = JsonValue()
if (data is Int) {
j.jsonData = JsonData.IntWrapper(data)
return j
}
if (data is String) {
j.jsonData = JsonData.StringWrapper(data)
return j
}
if (data is List<*>) {
j.jsonData = JsonData.ListWrapper(data.map {make(it)}.toMutableList())
return j
}
throw Exception("oops$data")
}
Nir
07/16/2020, 7:43 PMNir
07/16/2020, 7:43 PMval list = listOf(1,2,3)
val j2 = JsonValue.make(listOf(list, list, list))
Fleshgrinder
07/16/2020, 7:43 PMFleshgrinder
07/16/2020, 7:44 PMNir
07/16/2020, 7:44 PMNir
07/16/2020, 7:44 PMNir
07/16/2020, 7:44 PMNir
07/16/2020, 7:44 PMNir
07/16/2020, 7:45 PMNir
07/16/2020, 7:46 PMFleshgrinder
07/16/2020, 7:47 PMNir
07/16/2020, 7:48 PMNir
07/16/2020, 7:48 PMlistOf(ArbitraryClass())
Fleshgrinder
07/16/2020, 7:48 PMAny?
, only the types you actually support.Nir
07/16/2020, 7:49 PMList<Any?>
Nir
07/16/2020, 7:49 PMNir
07/16/2020, 7:49 PMFleshgrinder
07/16/2020, 7:49 PMList<Any?>
is good enough for JSON because JSON arrays contain arbitrary data.Nir
07/16/2020, 7:49 PMNir
07/16/2020, 7:50 PMFleshgrinder
07/16/2020, 7:50 PMAny?
type. 😉Nir
07/16/2020, 7:50 PMNir
07/16/2020, 7:51 PMFleshgrinder
07/16/2020, 7:51 PMlistOf(ArbitraryClass())
is covered by List<Any?>
Fleshgrinder
07/16/2020, 7:51 PMAny?
type are you thinking of?Nir
07/16/2020, 7:51 PMNir
07/16/2020, 7:51 PMNir
07/16/2020, 7:51 PMNir
07/16/2020, 7:52 PMList<Int>
, List<String>
, List<List<String>>
, etcFleshgrinder
07/16/2020, 7:52 PMNir
07/16/2020, 7:52 PMList<SomeClass>
Nir
07/16/2020, 7:52 PMFleshgrinder
07/16/2020, 7:52 PMNir
07/16/2020, 7:53 PMNir
07/16/2020, 7:54 PMNir
07/16/2020, 7:54 PMNir
07/16/2020, 7:55 PMNir
07/16/2020, 7:55 PMFleshgrinder
07/16/2020, 7:56 PMNir
07/16/2020, 7:58 PMNir
07/16/2020, 8:00 PMNir
07/16/2020, 8:00 PMFleshgrinder
07/16/2020, 8:02 PMNir
07/16/2020, 8:04 PMFleshgrinder
07/16/2020, 8:04 PMFleshgrinder
07/16/2020, 8:05 PMNir
07/16/2020, 8:05 PMNir
07/16/2020, 8:05 PMNir
07/16/2020, 8:05 PMJsonData
sealed class works pretty wellNir
07/16/2020, 8:05 PMNir
07/16/2020, 8:05 PMNir
07/16/2020, 8:07 PMfun maybeGet(index: Int): Dynamic? =
Nir
07/16/2020, 8:07 PMNir
07/16/2020, 8:07 PMNir
07/16/2020, 8:07 PMFleshgrinder
07/16/2020, 8:08 PMNir
07/16/2020, 8:08 PMclass JsonValue {
...
fun maybeGet(index: Int): JsonValue?
}
Fleshgrinder
07/16/2020, 8:08 PMNir
07/16/2020, 8:08 PMNir
07/16/2020, 8:08 PMNir
07/16/2020, 8:08 PMFleshgrinder
07/16/2020, 8:08 PMNir
07/16/2020, 8:09 PMFleshgrinder
07/16/2020, 8:09 PMAny?
is valid JSON.Nir
07/16/2020, 8:09 PMNir
07/16/2020, 8:09 PMNir
07/16/2020, 8:09 PMmaybeGet
should return that class (nullable)Nir
07/16/2020, 8:10 PMNir
07/16/2020, 8:10 PMNir
07/16/2020, 8:10 PMFleshgrinder
07/16/2020, 8:10 PMNir
07/16/2020, 8:11 PMdynamic
keywordFleshgrinder
07/16/2020, 8:11 PMNir
07/16/2020, 8:11 PMFleshgrinder
07/16/2020, 8:11 PMsomeJsonList.maybeGet(0)?.unwrap<String>()
Nir
07/16/2020, 8:11 PMNir
07/16/2020, 8:12 PMFleshgrinder
07/16/2020, 8:12 PMgetOrNull
would be more idiomatic Kotlin, this class is a little older than that convention.Nir
07/16/2020, 8:12 PMNir
07/16/2020, 8:12 PMNir
07/16/2020, 8:12 PM.unwrap
is another great example thoughNir
07/16/2020, 8:13 PMNir
07/16/2020, 8:13 PMFleshgrinder
07/16/2020, 8:13 PMNir
07/16/2020, 8:13 PM.unwrap<SomeUserType>()
that should really be a compilation errorFleshgrinder
07/16/2020, 8:13 PMNir
07/16/2020, 8:13 PMNir
07/16/2020, 8:14 PMNir
07/16/2020, 8:14 PMFleshgrinder
07/16/2020, 8:14 PMSomeUserType
without knowing about your JSON document and actually understanding if that JSON value can be deserialized to your SomeUserType
?!?Fleshgrinder
07/16/2020, 8:14 PMNir
07/16/2020, 8:15 PMx: Union[Int, String]
and reject something like x.unwrap<List<Int>>()
}Nir
07/16/2020, 8:15 PMFleshgrinder
07/16/2020, 8:15 PMx
can only be of Int
or String
but that doesn't say anything about a random JSON value you retrieved at runtime.Nir
07/16/2020, 8:16 PMNir
07/16/2020, 8:16 PMNir
07/16/2020, 8:16 PMNir
07/16/2020, 8:16 PMFleshgrinder
07/16/2020, 8:16 PMAny?
because we don't know if {"foo":"bar"}
can be deserialized to SomeUserType
and/or SomeOtherUserType
at compile time.Nir
07/16/2020, 8:16 PMNir
07/16/2020, 8:17 PMFleshgrinder
07/16/2020, 8:19 PMunwrap
. 🙂Fleshgrinder
07/16/2020, 8:20 PMasString
, asInt
, as...
functions.Fleshgrinder
07/16/2020, 8:20 PMList
and Map
cases are covered with the asList
and asMap
functions.Nir
07/16/2020, 8:21 PMNir
07/16/2020, 8:21 PMFleshgrinder
07/16/2020, 8:21 PMasList
returns List<Dynamic>
and you need to decide once more what it is.Nir
07/16/2020, 8:22 PMNir
07/16/2020, 8:22 PMNir
07/16/2020, 8:22 PMNir
07/16/2020, 8:22 PMList<List<int>>
immediatelyNir
07/16/2020, 8:22 PMNir
07/16/2020, 8:22 PMFleshgrinder
07/16/2020, 8:22 PMDynamic
class.Nir
07/16/2020, 8:23 PMNir
07/16/2020, 8:23 PMNir
07/16/2020, 8:23 PMauto j = json::parse(....)
vector<vector<double>> = j;
Nir
07/16/2020, 8:23 PMNir
07/16/2020, 8:24 PMstruct foo{};
vector<vector<foo>> = j;
Nir
07/16/2020, 8:24 PMFleshgrinder
07/16/2020, 8:29 PMNir
07/16/2020, 8:39 PMNir
07/16/2020, 8:39 PMNir
07/16/2020, 8:39 PMFleshgrinder
07/16/2020, 9:05 PMauto j = json::parse(....)
vector<vector<double>> = j;
This can never give you a compile time error because the compiler doesn't know what ...
is. If it's "{}"
it's not a vector<vector<double>>
. What the compiler may know is that both vector
and double
are possible values for the return (incl. nesting) but not if the parse result is actually a vector<vector<double>>
.Fleshgrinder
07/16/2020, 9:06 PMtypealias JsonValue = Boolean | List<JsonValue> | Map<String, JsonValue> | Number | String
(although Long
is actually not entirely representable in JSON but that's another story).Nir
07/16/2020, 9:08 PMNir
07/16/2020, 9:08 PMNir
07/16/2020, 9:08 PMvector<vector<Foo>> = j;
is a compile time errorFleshgrinder
07/16/2020, 9:08 PMNir
07/16/2020, 9:09 PMNir
07/16/2020, 9:09 PMNir
07/16/2020, 9:10 PMNir
07/16/2020, 9:11 PMFleshgrinder
07/16/2020, 9:32 PMMatteo Mirk
07/18/2020, 11:01 AM