https://kotlinlang.org logo
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
announcements
  • j

    Jason Ankers

    02/19/2021, 11:48 AM
    Whats the most idiomatic way to extend a primitive type in kotlin? For example in the context of an Android app, I want to build a type
    Force
    from
    Double
    which represents a force value converted to the appropriate unit (lbs/kg) based on user preferences. The type would encapsulate the conversion logic
    ➕ 1
    c
    • 2
    • 1
  • e

    escodro

    02/19/2021, 1:25 PM
    Hello, everyone! 😊 Is there a reason to the following code give me a Java warning? I made it nullable because this is a non-required foreign key.
    internal inline class CategoryId(val value: Long?)
    fun test(){
        CategoryId(12)
    }
    Warning:
    Use Long.valueOf(12) instead
    m
    a
    a
    • 4
    • 7
  • u

    user

    02/19/2021, 5:09 PM
    message has been deleted
    👍 2
    :thread-please: 1
    n
    • 1
    • 1
  • m

    Manuel Pérez Alcolea

    02/20/2021, 4:49 AM
    is there some elegant way in Kotlin to allow some syntax like the following one?
    class Asdf private constructor() {
        companion object {
            operator fun invoke(s: Asdf.() -> Unit) {
                this.s() // doesn't make sense, Asdf().s() would work instead
            }
        }
    }
    
    // to be called as follows:
    Asdf { }
    this doesn't work because there's no
    this
    in a companion object. I guess I could have a lazy property to an
    Asdf
    instance, but can I have no instance at all?
    r
    a
    +2
    • 5
    • 13
  • g

    Gabriel

    02/20/2021, 11:21 AM
    Hey folks, this is fairly small and succint but was wondering if there was a "nicer"/more kotlinesque way of doing it?
    val avatarList = mutableListOf<Int>(1,2,3)
    
    fun generateRandomAvatar(): Int? {
    	val pick = avatarList.randomOrNull()
    	if (pick !== null) avatarList.remove(pick)
    	return pick
    }
    a
    a
    +2
    • 5
    • 8
  • g

    Gabriel

    02/20/2021, 12:02 PM
    I'm passing a function with optional parameters as a parameter to another function
    fun addPlayer(
    		name: String,
    		avatar: Int? = generateRandomAvatar(),
    		id: String = UUID.randomUUID().toString()
    	) { dostuff }
    ...
    fun PlayerList(players: List<Player>, addPlayer: (String, Int?, String) -> Unit) {
        addPlayer("Player #${players.size}")<----error here
    }
    But I'm not sure how to convey in the signature that they're optional, maybe this isn't possible?
    t
    • 2
    • 5
  • m

    Mjahangiry75

    02/20/2021, 7:39 PM
    hey everybody I have a
    coroutine channel
    in a
    viewmodel
    , how can I collect changes in multiple places? I tried code below:
    #1
    channel.consumeAsFlow {}
    
    #2
    channel.consumeAsFlow {}
    
    #3
    channel.consumeAsFlow {}
    but only the first one will get triggered
    d
    y
    • 3
    • 5
  • s

    Slackbot

    02/21/2021, 1:07 PM
    This message was deleted.
    y
    f
    • 3
    • 3
  • f

    frank

    02/21/2021, 1:55 PM
    I was defining a variables const and I have doubts about good practices and most scalable design. What's a recommended ways? My Samples: • Method 1: Create Global without Wrapper. cons: No context and need added in name of variable. • Method 2: Create in Singleton Object.
    # Method 1: 
    private const val API_PATH = "<http://localhost:8080>"
    const val WELCOME_ENDPOINT = "$API_PATH/welcome"
    
    # Method 2:
    object EndPoints {
      private const val API_PATH = "<http://localhost:8080>"
      const val WELCOME = API_PATH + "/welcome"
    }
    v
    y
    m
    • 4
    • 5
  • m

    Marc

    02/21/2021, 6:54 PM
    I've come across the use of a sealed class in the Jetpack Compose Jetnews example code that I think has general applicability. I'm new to Kotlin and don't understand this construction of a generic class with 2 type parameters. I'd appreciate pointers to docs or articles that explain it. Thanks!
    sealed class Result<out R> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
    }
    👌 1
    ✅ 2
    d
    d
    a
    • 4
    • 5
  • m

    Mark

    02/21/2021, 7:24 PM
    Hey, this may be a dumb question but when adding the Kotlin plugin, the std will be automatically added to
    compileClasspath
    abd
    runtimeClasspath
    , is it possible to disable this and have it only as
    testImplementation
    ?
    j
    • 2
    • 2
  • a

    Adam

    02/22/2021, 1:14 AM
    Does anybody know how to request a slack invitation recently? The signup page just says to contact an admin if you don't have a Jetbrains email address.
    a
    • 2
    • 3
  • g

    Gleb Garipov

    02/22/2021, 9:55 AM
    Hi! Let's say I have a sealed class WriteOperation, with some data classes as children and I want to convert them to corresponding WriteModel classes of mongodb or sql query templates for relational db. So my code for now looks like this:
    sealed class WriteOperation {
      data class Insert(...some props): WriteOperation()
      data class Delete(...some props): WriteOperation()
      data class Replace... and so on
    }
    // And then in mongo-related package I do:
    fun WriteOperation.toMongoModel(): WriteModel = when (this) {
      is WriteOperation.Insert -> InsertOneModel(...initialization)
      is WriteOperation.Delete -> DeleteOneOperation(...initialization)
      is WriteOperation.Replace -> ...
      ... and also around 12 other conditions
    }
    // Same thing happens with SQL:
    fun WriteOperation.toSqlQuery(): SQLQuery = when (this) {
      ...long and painful list
    }
    Is there any way of replacing those long when expressions with some kind of inheritance, extension or composition without referencing Mongo or SQL implementation in sealed classes?
    y
    c
    • 3
    • 5
  • a

    Animesh Sahu

    02/22/2021, 12:44 PM
    Is there a way to dump IR, possibly a online service or something? playground doesn't seem to have any options regarding...
    y
    • 2
    • 1
  • t

    tony

    02/22/2021, 11:05 PM
    I just noticed I have some builds that use the repo
    <https://dl.bintray.com/kotlin/kotlin-eap>
    for accessing preview versions of Kotlin. What repo can I use instead, to remove my reliance on anything bintray/jcenter-related?
    v
    • 2
    • 4
  • s

    scottiedog45

    02/23/2021, 12:26 AM
    I have a few jobs in a class that I would like to set to null can cancel, but obviously this doesn't work, I get a
    val cannot be reassigned
    error, i think because i don't want to assign the local value in the forEach closure, but the property of the parent class. How could I do something like this?
    listOf<Job?>(
                uiJob,
                authJob,
                videoEventsJob,
                videoJob,
                countdownJob
            ).forEach {
                it?.cancel()
                it = null
            }
    e
    e
    +2
    • 5
    • 5
  • u

    user

    02/23/2021, 11:53 AM
    Jetpack Compose for Desktop: Milestone 3 Released The Compose for Desktop journey continues! Since the last milestone release of Compose for Desktop, we’ve done our best to bring you an even better experience when building desktop UIs in a modern and declarative style. Today we’re publishing Compose for Desktop Milestone 3, which introduces significant rendering and interoperability improvements, and makes it even […] The post <a href="https://blog.jetbrains.com/kotlin/2021/02/jetpack-compose-for-desktop-milestone-3-released/"...
    🔥 14
    :kotlin-intensifies: 22
    👍 4
    n
    • 1
    • 1
  • m

    mending3

    02/24/2021, 4:50 AM
    got-stuck let's say I have this code:
    val string = "<p></p>this<p></p>"
            
    val arrs = listOf("<p data-id=\"1\"></p>", "<p data-id=\"2\"></p>")
    
    var replacedString = ""
    
    arrs.forEach {
        val pTag = "<p></p>"
    
        replacedString = string.replace(pTag, it)
    
    }
    
    println(replacedString)
    It should show
    <p data-id="1"></p>this<p data-id="2"></p>
    , but it shows
    <p data-id="2"></p>this<p data-id="2"></p>
    instead
    n
    p
    +3
    • 6
    • 25
  • e

    einsjannis

    02/24/2021, 9:16 AM
    I have a file with a lot of functions witch all have the same name and only the amount of arguments and the return type changes, every time I start to type the name of the function outside of the file, Intelij freezes almost immediately. Changing the name of the functions to contain the amount of arguments does not change anything. Does anyone know what the issue is and how I can fix this.
    p
    a
    • 3
    • 6
  • g

    ghosalmartin

    02/24/2021, 9:49 AM
    Anyone know if theres any particular way to inject our own
    Pattern
    object to
    Regex
    although given its a static I don’t think it’d make much of a difference
    i
    • 2
    • 2
  • x

    xii

    02/24/2021, 10:57 AM
    Is there any way to be able to pass a condition based on a data class property as parameter? (thread)
    y
    • 2
    • 11
  • m

    mending3

    02/24/2021, 11:48 AM
    how do I deal with this?
    :google: 3
    v
    • 2
    • 1
  • m

    mending3

    02/24/2021, 1:41 PM
    val string = "8% of 25 is the same as <img class=\"limit\">There are no heroes in a punk rock band <img class=\"limit\">"
    
            val arraySearch = arrayOf("<img class=\"limit\">", "<img class=\"limit\">")
    
            val arrayReplacement = arrayOf("<img class=\"another-limit\" data-id=\"1\">", "<img class=\"another-limit\" data-id=\"2\">")
    
            arraySearch.forEachIndexed { index, it ->
                string.replace(it, arrayReplacement[index])
            }
    println(string)
    the string doesn't get replaced. still showing
    8% of 25 is the same as <img class="limit">There are no heroes in a punk rock band <img class="limit">
    where it should have been
    8% of 25 is the same as <img class="another-limit" data-id="1">There are no heroes in a punk rock band <img class="another-limit" data-id="2">
    y
    n
    • 3
    • 13
  • u

    123

    02/24/2021, 2:24 PM
    `companion object {
        val SORTING_COLUMNS = mapOf(X to "Y")
        val DEFAULT_SORTING_COLUMN: String = SORTING_COLUMNS[X]!!
    }`
    Anything I could do here to avoid reductant
    !!
    ?
    w
    v
    n
    • 4
    • 4
  • f

    frank

    02/24/2021, 6:14 PM
    I have seen that it is not available compound assignment for bitwise operators in Kotlin. Do you know if it could be implemented in the future or why it might not be possible? Sample:
    //Java
    n >>= 1;
    //Kotlin
    n = n shr 1 // E.g. n shr= 1
    ☝️ 1
    😢 1
    e
    • 2
    • 1
  • a

    Alfred Lopez

    02/24/2021, 10:08 PM
    fun myFunc(handler: Result<String> -> Unit) ....
    n
    • 2
    • 13
  • k

    Kevin

    02/25/2021, 8:42 AM
    hi all, would like to ask for some suggestion on which is a better approach, to use
    include
    or
    recyclerView
    ? this is probably will be long, but i'll try to keep it simple. so i have a layout, where in that layout there is 3 sub-menu clickable tab. the 3 sub-menu tab has about 90% same UI, where it's difference only on the icon image and title text. because i'm originally will use
    recyclerView
    , i had create the sub-menu UI on different xml file. i was thinking to use
    recyclerView
    and set the
    itemCount
    to 3, and then set each item UI differences(icon & text) programatically. but in that moment, i got a thought what if i create the whole 3 sub-menu tab on that separate xml file and then called the sub-menu tab file on main layout by using
    include
    . because of this, i'm quite confused, on which is recommended to use for a better approach on making layout UI? thank you
    :stackoverflow: 2
    r
    • 2
    • 1
  • g

    Gerard Bosch

    02/25/2021, 6:21 PM
    Hi there! I'm trying to find if is possible in Kotlin to define a custom accessor for a class or data class that simply returns the non-nullable version of a class field (using a fallback value). Can't figure out how the syntax would be for the following:
    data class MyDataClass(private val myProperty: BigDecimal?) {
                val myProperty: BigDecimal = myProperty 
                    get() = field ?: BigDecimal.ZERO       // <-- I want to just expose the non-nullable version of the property
            }
    👆 I've just tried the above as per what I could grasp from https://kotlinlang.org/docs/properties.html#getters-and-setters but can't make it work 😬 Is that possible to redefine a property accessor in such way? If it is, which syntax/construct should achieve it? Thx!
    r
    n
    m
    • 4
    • 19
  • n

    nkiesel

    02/25/2021, 8:05 PM
    We started weekly Kotlin discussions in my company. This often involves playing around with some code. What tools are you guys using for this? Options I'm aware of are • screen sharing - does not allow for multiple people to edit • Intellj "code with me" - heavy (e.g. requires install) and seems to loose synchronized view once in a while • codebunk - interview tool, does not support latest Kotlin What I really would like would be a collaborative mode in "play.kotlinlang.org" but that does not seem to exist. Any other suggestions?
    n
    b
    +2
    • 5
    • 18
  • e

    Endre Deak

    02/25/2021, 8:21 PM
    I’m struggled with a problem around using kotlin’s built-in
    Result
    class. I’m trying to go through a process which would look like: • do step 1, if fail then return with an error • do step 2 using step 1 result, if fail then return with an error • … so far what I coded is kind-of ugly:
    runCatching { step1() }
        .fold(
            onFailure = { myCustomError("step1") },
            onSuccess = { step1Result -> 
                runCatching { step2(step1Result) }
                    .fold(
                        onFailure = { myCustomError("step2") },
                        onSuccess = { ... 
            ...
         )
    I’m pretty sure there’s a better way to do this - any suggestions?
    n
    o
    n
    • 4
    • 75
Powered by Linen
Title
e

Endre Deak

02/25/2021, 8:21 PM
I’m struggled with a problem around using kotlin’s built-in
Result
class. I’m trying to go through a process which would look like: • do step 1, if fail then return with an error • do step 2 using step 1 result, if fail then return with an error • … so far what I coded is kind-of ugly:
runCatching { step1() }
    .fold(
        onFailure = { myCustomError("step1") },
        onSuccess = { step1Result -> 
            runCatching { step2(step1Result) }
                .fold(
                    onFailure = { myCustomError("step2") },
                    onSuccess = { ... 
        ...
     )
I’m pretty sure there’s a better way to do this - any suggestions?
n

nanodeath

02/25/2021, 8:25 PM
val result1 = try { step1() } catch (e: Exception) { myCustomError("step1") }
val result2 = try { step2(result1) } catch (e: Exception) { myCustomError("step2") }
but with like a dozen more newlines in there. doesn't use Result but maybe you can say
.get()
to force it to throw or something.
o

Orhan Tozan

02/25/2021, 8:44 PM
Yes, I've also faced this problem, and solved this by the following ext function
fun <T, R> Result<T>.letIfSuccess(block: (T) -> Result<R>): Result<R> = 
    when(this) {
        is Result.Failure -> this
        is Result.Success -> block(this.data)
    }
Now, you can chain your results with letIfSuccess, and prevent the nesting hell
Note: I am using this extension function on my own custom Result type. You can apply it to kotlin.Result as well
Now my control flow is really clean without ugly early returns or throwing exceptions
n

Nir

02/25/2021, 8:51 PM
I think the simplest is simply to do
runCatching
o

Orhan Tozan

02/25/2021, 8:52 PM
@Nir he is already using runCatching.
n

Nir

02/25/2021, 8:54 PM
I'm not sure how it ended up so ugly with runCatching
typically the idea is that you're calling functions that return result
val r = runCatching {
    val x = someFunc().getOrThrow()
    val y = someFunc2().getOrThrow()
}
etc
that's the whole point of using runCatching; you just use getorThrow
you don't use fold
o

Orhan Tozan

02/25/2021, 8:57 PM
Not true, runCatching + fold is a nice pattern of transforming a throwing function to a one that returns a result
Its a quick bridge from exception world to result world
Im using runCatching and never used getOrThrow() myself
n

Nir

02/25/2021, 9:09 PM
how is it a nice pattern?
If you use
fold
you don't really need runCatching
o

Orhan Tozan

02/25/2021, 9:16 PM
Function foo() returns a string or throws. When I wrap foo() with runCatching, it doesnt throw anymore, and returns a result<String> instead.
n

Nir

02/25/2021, 9:16 PM
yes...
o

Orhan Tozan

02/25/2021, 9:16 PM
Then now, I can use fold to react to the result if its a failure or success
n

Nir

02/25/2021, 9:17 PM
Sure, you can, it's just a matter of the best tool for the job. the point of runCatching is that it lets you chain throwing things (or Results since they easily can throw)
o

Orhan Tozan

02/25/2021, 9:18 PM
Why chain? You can use runCatching to simply wrap a throwing function with a result
So you don't have to use try {} catch
n

Nir

02/25/2021, 9:19 PM
nobody's suggesting using try catch to begin with
o

Orhan Tozan

02/25/2021, 9:20 PM
Ok but I don't understand your point then. It looks like you are saying that runCatching { foo() }.fold(...) is of no need, and you could foo() directly instead?
n

Nir

02/25/2021, 9:21 PM
I was talking about using runCatching for the purpose of composing function that error
o

Orhan Tozan

02/25/2021, 9:22 PM
Not sure what function that error means
n

Nir

02/25/2021, 9:23 PM
functions that can error? throw or return Result?
o

Orhan Tozan

02/25/2021, 9:24 PM
yes, but we all agree on that I think we use runCatching for error handling
n

Nir

02/25/2021, 9:26 PM
let's say you use your approach on the OP code
you're going to have the original function call, then
fold
, and then letIfSuccess
3 calls for every step of the computation
sorry, the original function call, runCatching, then fold, then letIfSuccess
assuming the original function throws
o

Orhan Tozan

02/25/2021, 9:28 PM
You dont need fold with letifsuccess
n

Nir

02/25/2021, 9:28 PM
where are you transforming to the custom error type?
none of the other places let you do that transformation
The entire problem here is the custom error transformations. Otherwise, you don't need anything other than a single runCatching around the whole computation
o

Orhan Tozan

02/25/2021, 9:29 PM
Yeah I think the example pseudo code is too pseudo for us to really understand what he wanta
n

Nir

02/25/2021, 9:29 PM
val x = runCatching {
     step2(step1())
}
No, not at all, it's very clear what he wants
No, not at all, it's very clear what he wants
He wants to transform the errors from step1 and step2 into his own custom errorrs
val x = runCatching {
    val first = runCatching { step1() }.getOrElse { // throw custom exception type }
    val second = runCatching { step2(first) }.getOrElse { // throw custom exception type }
}
o

Orhan Tozan

02/25/2021, 9:31 PM
Then what does his function return?
Any
? Or is it a supertype of the custom error type and succeasfull path return type
n

Nir

02/25/2021, 9:31 PM
@Endre Deak sorry we wandered around a bit and I didn't fully 7understand at first, but I think that code is pretty nice
His function returns a result
o

Orhan Tozan

02/25/2021, 9:33 PM
Your last example is throwing custom exxeptions? While OP doesnt want to throw custom exceptions, he wants to return Custom Error objects
n

Nir

02/25/2021, 9:34 PM
It's going to throw and immediately get caught by the runCatching
the block of code I showed will not throw and
x
will be a Result, which is what OP wants
o

Orhan Tozan

02/25/2021, 9:34 PM
Yeah but it will still be type of Excpetion, not custom error like OP indicated
n

Nir

02/25/2021, 9:35 PM
That's a good point, the OP's code isn't fully clear in the sense that the onFailure and onSuccess don't seem to return the same type
so the OP will get an Any
o

Orhan Tozan

02/25/2021, 9:36 PM
Yeah its too pseudo at the moment
n

Nir

02/25/2021, 9:36 PM
That said, maybe this is closer to what he meant, and `x`'s type is always better than having an Any
you can always try to cast the error type back, like you would cast an Any, and the successful result is handled
e

Endre Deak

02/25/2021, 10:03 PM
Ok, to make the OP more clear -
myCustomError
would return with a custom result object indicating the success of the entire process or the failure (at which step and what the issue was). So if I’m flattening out, what I want to achieve nicely is something like:
data class MyCustomResult(
   val code: ResultCode,
   // .. details)

val firstRes = runCatching { first() }
if (firstRes.isFailure) {
    return MyCustomResult(STEP_1, first.exceptionOrNull())
}

val secondRes = runCatching { second(firstRes.getOrNull()!!) }

if (secondRes.isFailure) 
...
...
n

Nir

02/25/2021, 10:03 PM
What's the overall return type?
e

Endre Deak

02/25/2021, 10:04 PM
MyCustomResult
n

Nir

02/25/2021, 10:04 PM
Then just do a run block
With runCatching around the throwing function
And return in the getOrElse block
e

Endre Deak

02/25/2021, 10:06 PM
ohh
n

Nir

02/25/2021, 10:06 PM
You can write a tiny function that just combined runCatching with getOrElse
Could call tryOrElse
Although maybe it's not worth it
Since you need to pass two lambdas
e

Endre Deak

02/25/2021, 10:08 PM
but
getOrElse()
returns with
Any
so an idea of doing something like
runCatching { first() } 
.getOrElse { firstError() } 
.let { f -> second(f) } 
.getOrElse { ... } 
...
won’t work because
f
is
Any
instead of the result type
n

Nir

02/25/2021, 10:26 PM
The thing is that your custom result type is kind of misnamed, it only holds errors, not successful results
Ah, i see
Can you make your custom result type inherit from Throwable?
Sorry, custom error type
And then just use
Result
instead of MyCustomResult
otherwise, you'll need to reimplement a lot of
Result
-like machinery in MyCustomResult
View count: 6