<@U0RM4EPC7> In your presentation repo, you used E...
# arrow
d
@simon.vergauwen In your presentation repo, you used Either.catchOrThrow in the either example whereas in the context params example a regular try/catch... is that your preference? Also, there's nested recovers in the context params example... isn't there something better (Arrow's supposed to be more imperative...., maybe in that case two/three levels nesting isn't so bad?). And last, you put the transaction OUTSIDE the recover, whereas in the presentation it was inside... (as far as I remember...?). Btw congrats for the nice presentation, I'm sure it'll attract a bunch of new users 😉!
thank you color 1
s
Hey @dave08, Good questions, and feedback. Hmm, preference not really. Not sure I really have one, as long as it's correct 😅 I used
try/catch
because I wanted to limit foreign things, since there is people not familiar with Arrow at all also following the talks. The nested recover is indeed super annoying, but not fixable until we get context parameters I am afraid. Then we could do something like:
Copy code
recover(
  { context(Raise<E1>, Raise<E2>) () -> A },
  { e1: E1 -> A }
  { e2: E2 -> A }
)
And last, you put the transaction OUTSIDE the recover, whereas in the presentation it was inside... (as far as I remember...?).
You're right, I think I accidentally pushed that when I was talking to someone before the actual talk 😅 I pushed a fixed
d
but not fixable until we get context parameters I am afraid.
So that feature is not available in the current context parameters implementation?
And when it is, you'd provide a bunch of overloads for each number of raise contexts used?
s
The functionality is available, so you can define it yourself, or from an experimental library, but not something we can expose from Arrow without introducing breaking changes when context parameters are released
d
Isn't there such a library for simplifying Arrow with Context params (that also has all the with() implementations with multiple params...), maybe there could be something there for those who want to use those now...?
s
@Youssef Shoaib [MOD] was experimenting with it, and I am interested in experimenting with it 😅 We definitely can start such a library! Would be good preparation for when they're released
I already have in my head how I want to adapt Arrow, but it involves very little changes, and most will be binary and source compatible. New more powerful APIs is where the interesting stuff is going to happen
Like being able to define DSLs that combine Ktor, and Arrow and potentially even Exposed
I am thinking of something like this:
Copy code
data class MyError(val msg: String)

context(Raise<MyError>)
fun hello(name: String): String {
  ensure(name.isNotBlank()) { MyError("Name is blank") }
  return "Hello, $name"
}

fun MyError.toStatusCode(): HttpStatusCode = TODO()

io.arrow.ktor.get("MyGetter", MyError::toStatusCode) {
  val name = path("name") // raises HttpStatusCode.NotFound
  hello(name) // Raises MyError which is automatically translated through `MyError::toStatusCode`
}
So build a
Raise
DSL for Ktor where
HttpStatusCode
is the error, and you use
withError
, to turn your own types into
HttpStatusCode
and then you can call them from within the Ktor Raise DSL.
I think you've had a request about this once as well, I think context parameters allow us now to define a thin library with some cool utilities
Similarly you could do:
Copy code
exposed {
  // any SQLException is turned into a nice Raise<SQLState> where SQLState is an enum of all SQL errors.
}
d
I currently did make a bunch of utility functions like that for parameters... but for the response to have a Raise DSL, looks very interesting! Although we use #komapper for db access (I didn't like #exposed too much...), but I guess the same could be done there... originally I thought of just making a wrapper around their
db.runQuery(...)
to transform exceptions to raise errors, but it seems like a Raise DSL might be nicer... is it easy to make (maybe have a common set of errors for multiple db libraries, and have an implementation for each? A bunch use Sql Delight for KMP, and there's probably others... somehow unifying error handling for them might be nice if possible...)
s
Yes, good point. I haven't used Exposed for a while myself, and I've used SQLDelight a lot. I think a single DSL might be providable since you should be able to get this information from JDBC/SQLException directly as well which all of these libraries use under the hood.
d
Except that #komapper also has an implementation for R2Dbc with coroutines... I think there was an old issue in exposed that discussed R2dbc, but I'm not sure what the new team will do with it...
s
Yes, good point! Not sure which exception hierarchy R2DBC uses, but I assume it respect the SQL codes anyway