Feature request: `nullableLossy` to convert any fu...
# arrow
c
Feature request:
nullableLossy
to convert any function declared with
Raise
, transforming any failed values in
null
β†’ https://github.com/arrow-kt/arrow/issues/3138
j
That name cannot be hard to find?
s
So an alias for
recover({ blabla() }) { null }
, right?
There has been a discussion before about
getOrNull { }
but that looks weird πŸ˜„
effect { }.getOrNull()
also works
c
So an alias for
recover({ blabla() }) { null }
, right?
Yes, that's an easier way to write it than
either {  }.getOrNull()
j
Yeah, first I think was
getOrNull { }
, but it is a global function which looks generic but only works with
Raise
, I don't think it is a good name
s
I'm definitely open for such a feature, but it's very hard to name πŸ˜…
j
I was thinking something related to
runCatching
, but I cannot get a good name... yeah, hard name
c
That name cannot be hard to find?
Honestly, I have always expected
nullable
to behave like this. I believe many other people may as well, which is the reason I want to name it
nullableXXX
, so you can discover it through auto-complete
πŸ‘ 1
j
Just brainstorming: β€’
fromEffectOrNull { }
β€’
fromRaiseOrNull { }
Yeah I understand you, but from my point of view, I wouldn't find that name if I don't look for it on the docs, I would look to something that start or at least includes
raise
in the name
c
from
isn't really a prefix I see often? β€’
effectOrNull {}
: but it's called
Raise
now, right? Why introduce something using the old name? β€’
raiseOrNull {}
: that really looks like something that raises, not something that capture raises
I would look to something that start or at least includes
raise
in the name
I don't know, all existing builders are named after what they produceβ€”it's not
eitherFromRaise
,
nullableFromRaise
, etc
j
yeah, I don't like
from
too, just throwing ideas
s
recoverNull { }
?
πŸ‘€ 1
πŸ€” 1
As an alias for the
recover({ }) { null }
pattern πŸ€”
recoverOrNull
seems incorrect πŸ˜„
j
recoverOrNull
s
That doesn't seems correct, then I guess it should be
recoverWithNull { }
πŸ˜•
c
How readable would it be in a code review without IDE features? I would probably assume
recoverNull
means "do some recovery when the block returns `null`"
βž• 1
recoverWithNull
sounds fine
I'm not sure what the case against
nullableLossy
is, though: it's a variant of
nullable
, but swallows the error
j
Wouldn't
recover { }.orNull()
correct?
s
Not a big fan of
Lossy
tbh πŸ˜…, and creating more sublanguage
recover { }.getOrNull()
is what you could do with
effect { }.getOrNull()
but it's the same in length as what @CLOVIS is trying to solve
either { }.getOrNull()
c
Well, my goal is mostly readability:
Copy code
fun fooOrNull() = either { // why it is building an either?
  // a lot of code
}.getOrNull() // nobody expects something to happen after the closing brackets
j
@CLOVIS As I am not an expert on FP in general, my POV is there are 0 well-known APIs in Kotlin with
nullable
as a prefix, so for a beginner, it will be impossible to find it.
s
there is
nullable { }
in Arrow πŸ™ƒ
j
I know, I mean in Kotlin stdlib
c
^ that's why I wanted to reuse the name πŸ™‚
j
Personally I liked the move of Arrow to looks like Kotlin with
getOrNull
APIs
βž• 1
c
I guess this is a bit better:
Copy code
fun foo() = recover({
    // a lot of code
}) { null }
but the brackets have to be inside the parens, which I'm not a fan of for large functions, it breaks the mental model of "`either` is a decorator of the rest of the function"
j
I am not a fan of using
({
, I use named params in those use cases.
s
No-one is a fan of
({
πŸ˜‚ it's a necessary evil sadly somtimes
❀️ 1
c
Copy code
fun foo() = recover(
    block = {
        // a lot of code
    },
    recover = { null }, 
)
is readable, but it's much more verbose, and now the code is 2-levels deep inside of 1
s
Not sure if that is more readable either πŸ€”
c
For someone who's not familiar with Arrow, I believe it is, because it makes more explicit what the happy path is and what the recovery path is
s
I'd recommend
either { }.getOrNull()
tbh, it's probably going to be most readable
πŸ‘ 1
c
In short functions, probably, but as soon as it's more than 5 or 6 lines, I really don't expect an
either {}
call to have anything at its end
j
What about
nullable {}
? But it would need to have the same package as the original one in order to have priority
c
What about
nullable {}
?
I feel like it would be really confusing to have two functions with the same name, one of which swallowing errors silently
s
Those would conflict anyway.
s
I’d always go with existing functions like
either { }.getOrNull()
or just
effect {}.getOrNull()
here, and if a new function was introduced in our local codebase I’d probably advocate against it. Easier to use the standard tools that everyone understands and use them together as they are meant to be used, as opposed to introducing yet another function which simply wraps 2 function calls which will be looking foreign to most arrow users.
d
I think it's a good idea to hook into a developer's muscle memory (basically the principle of least surprise), so try and find a name which the developer will likely try out first or recognize from another library.
runCatching
has getOrNull
Optional
has getOrNull Casting methods have 'orNull' variants such as
toIntOrNull
as a way to turn the exception into a null-value
πŸ‘ 2
a
sorry for being late to the discussion, but at some point we discussed this too, and we came to the following design: use
nullable
but introduce
ignoreErrors
that does exactly that https://apidocs.arrow-kt.io/arrow-core/arrow.core.raise/-nullable-raise/ignore-errors.html
(I'm writing a few more details in the PR itself)
c
Oh, nice, so it's used like this?
Copy code
fun fooOrNull() = nullable {
    ignoreErrors { foo() }
}
a
yep
c
Then I'd like to change my issue from proposing a new construct to β€œmentioning ignoreErrors in nullable's documentation” 😊
I'll edit it later, and maybe I'll create a PR too if I have time
a
thanks, you've been wonders for us discovering all the hidden corners of Arrow we forgotten to cover in the docs πŸ˜„ ]
πŸ˜… 1
βž• 2
πŸ‘ 1
K 1