https://kotlinlang.org logo
Title
l

louiscad

01/11/2018, 11:07 AM
Does anyone think having a
sealed class
inside another one is a bad idea? My use case is to represent the states of
CameraCaptureSession
from Android Camera2 API (see these state callbacks: https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession.StateCallback.html) Here's my updated
sealed class
that is inside a custom
CamCaptureSession
class:
sealed class State {
    sealed class Configured() : State() {
        companion object : Configured()
        sealed class InputQueueEmpty : Configured() {
            companion object : InputQueueEmpty()
            object Ready : InputQueueEmpty()
        }

        object Active : Configured()
    }

    sealed class Closed : State() {
        companion object : Closed()
        object ConfigureFailed : Closed()
    }
}
c

Czar

01/11/2018, 11:16 AM
In fact it was the only way it worked before the update to 1.1 (I think). So your code is good and sound!
l

louiscad

01/11/2018, 11:24 AM
@Czar I knew this, I'm talking about nesting 2 sealed classes. Did you notice it? Using it seems fine BTW
c

Czar

01/11/2018, 11:26 AM
Oh, that, yeah. Well, if that makes sense for your use case (I don't know Android frameworks) I don't see anything criminal in there 🙂
👍🏽 1
l

louiscad

01/11/2018, 11:35 AM
Alright, I'm adding a third level of
sealed class
Wait, a lot more actually. Hopefully this will allow to get rid of the callback hell and go all #coroutines
r

raulraja

01/11/2018, 12:13 PM
Nesting sealed classes is not a bad idea IMO. It's a fine representation of union types and the compiler will warn you when missing cases in
when
etc.
You may not need Optics for this but if you want to easily compose transformations in such nested structures you may also want to look into Prisms and Lenses which will give you composable functions you can use to navigate the graph of sealed classes and data classes on your model http://arrow-kt.io/docs/optics/lens/ http://arrow-kt.io/docs/optics/prism/ and that are far more easy to deal with that deep nested when statements and nested
copy
calls.
l

louiscad

01/11/2018, 1:31 PM
@raulraja I do not even have to write nested when branches for nested sealed classes (3 levels deep here)! The following code compiles with the snippet of the first message of this thread:
val stateDependentValue = when(sessionState) {
    CamCaptureSession.State.Configured -> TODO()
    CamCaptureSession.State.Configured.InputQueueEmpty -> TODO()
    CamCaptureSession.State.Configured.InputQueueEmpty.Ready -> TODO()
    CamCaptureSession.State.Configured.Active -> TODO()
    CamCaptureSession.State.Closed.ConfigureFailed -> TODO()
    CamCaptureSession.State.Closed -> TODO()
}
I could as well use
is
to reduce the number of branches if I need to perform the same thing for any
Configured
state for example. About Optics from Arrow: I have a hard time understanding what is the purpose of it and in which use cases it could be used... is there a blog post or something to help demystify this?
t

tschuchort

01/11/2018, 1:37 PM
it's a good idea imo
r

raulraja

01/11/2018, 2:38 PM
@louiscad that's great, my suggestion was just for cases where you need to update the internal values of your immutable model graph and they are deeply nested. The current approach with
copy
does not scale well. The link I pasted about lenses has 2 sections
Composition
and
Generating Lenses
that show an example of the issue of having nested
copy
methods and a solution with Lenses. Lenses are just functions with
get
&
set
that can be composed together into a new function that gives you back a copy of the object with your updated changes. Prisms are the same but to work with nested sealed hierarchies. I understand in your case you don't need it since it's a simple ADT for a specific purpose but thought I'd mention in any case since nesting sealed classes eventually becomes hard to maintain when attempting to update their nested values.
👍🏽 1
r

radityagumay

01/12/2018, 2:14 PM
That's okay, it just like you create State machine.