<@UGPMTH1D5> <@UE3D4UE15> If `objectMapper.convert...
# arrow
r
@Derek Berner @Bob Glamm If
objectMapper.convertValue
can fail with an exception then it should be suspended and you should be using
IO
instead of
Try
. Try is going away or going to be modified because it can’t suspend effects or run suspend functions. If we make Try support suspend then we have IO. On a different token you can encode internally all your error handling efforts including validation without implying fail fast or error accumulation and then export a la carte in your public API the error strategies for each data type that you want to support. This link supports with the same code both fail fast and error accumulation https://arrow-kt.io/docs/patterns/error_handling/#example--alternative-validation-strategies-using-applicativeerror
d
Hey,
objectMapper.convertValue
is a 3rd party library
It can be wrapped in
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
but cannot be directly suspended
And it neither blocks nor suspends
b
If that's Jackson shouldn't that be IO { objectMapper.convertValue(...) } anyway?
since I think convertValue can throw an exception
r
Yes, even if it's not suspended if it throws exceptions should be inside a suspend function or IO
d
But... then I lose the ability to accumulate errors because IO is always fail-fast
I'm not seeing from the link above how to make that work with IO, because IO is of type
ApplicativeError<ForIO, Throwable>
b
As far as accumulating errors go, don't you have two modalities?
assert(args.size == 3)
must fail fast in order for the subsequent
objectMapper.convertValue()
methods to properly execute
but then you want
objectMapper.convertValue()
to all execute?
d
I suppose that's true, the other 3 depend on the successful execution of the first
But if it's >3, then they should still execute, to be "nice" to the RPC client
b
That just changes the condition in the assert rather than the modalities
d
Regardless. Even if the first one cannot execute in parallel with the rest, the rest should still execute in parallel and accumulate, so the caller can fix all their errors at once
b
oh, so if args.size == 2 then also accumulate any errors from the first two `objectMapper.convertValue()`s?
d
yeah, and if
args.size == 3
then accumulate errors from all 3, etc
I'm seeing that the first one should probably use a flatMap
b
I think I would wind arguments through Option or flatMap Validated instead of the first one
Maybe IO.traverse() over the validation conditions?
d
But
traverse
isn't polymorphic
a, b, and c are of generic types A, B, and C
hence the use of
Applicative
b
ahh, right, you'd be shoehorning types
d
traverse
exchanges polymorphism for variadicity (is that even the right term??)
b
my wild guess is that HLists would be most useful to you, except those don't exist in Kotlin
d
I could create a shortcut type
ValidatedIO<E: Semigroup<E>, Z> = IO<Validated<E,Z>>
Then make it implement
ApplicativeError<F, E>
Which would require importing the optional
kapt
libraries
b
If you want
*
why not just use
ApplicativeError<Any, Nel<Throwable>>
?
if you truly don't care about the error type
d
Sorry, I don't mean the Kotlin wildcard. I mean the type constructor
ForXXX
that Arrow implements through annotation processing magic
b
(maybe that's a dumb question; my memory of the original example is foggy)
d
The first type arg for
ApplicativeError
is a type constructor that represents the functor type being used
Not an error type
r
@Bob Glamm there is HList in Arrow generic but there is no automatic type level derivation at compile time.
@Derek Berner I’ll take a look at your example. Are you attempting to collect errors from operations that may fail?
d
Yes
r
I’ll play with it and see if I can come up with something, will post here when ready
d
objectMapper
is a JSON parser - this is happening near the point of the HTTP request handler
r
so you are already in IO at that point?
d
Kind of. It's in a
suspend fun
r
ok so yeah
d
And it has a
PipelineContext
receiver which extends
CoroutineScope
If
Validated
had a monad transformer
ValidatedT
I could work with that
r
yeah I see what you mean but there should be an alternative way with IO and the Concurrent hierarchy. Is
objectMapper
thread safe?
d
According to stackoverflow, yes
r
cool
d
😞
I've crashed the IntelliJ compiler with Kotlin type args, too