dart-lang / language

Design of the Dart language
Other
2.65k stars 201 forks source link

Algebraic Data Types (ADTs, Sealed Classes, Enum with associated values) #349

Closed ZakTaccardi closed 1 year ago

ZakTaccardi commented 6 years ago

ADTs are a very important part of any modern programming language.

Imagine you have a network call that submits login credentials. This call can:

In Kotlin, the return value could be represented as the following sealed class

sealed class LoginResponse {
    data class Success(val authToken) : LoginResponse()
    object InvalidCredentials : LoginResponse()
    object NoNetwork : LoginResponse()
    data class UnexpectedException(val exception: Exception) : LoginResponse()
}

Kotlin's when statement unwraps this beautifully, smart casting LoginResponse.

fun on(loginResponse: LoginResponse) {
    return when (loginResponse) {
        is LoginResponse.Success -> {
            // direct access to auth token available w/o need to cast
            loginResponse.authToken
        }
        is LoginResponse.InvalidCredentials -> {

        }
        is LoginResponse.NoNetwork -> {

        }
        is LoginResponse.Unexpected -> {
            // direct access to exception available w/o need to cast
            loginResponse.exception
        }
    }
}

Sadly, languages like Java and Dart are unable to elegantly express this concept (ADTs). For a best case example, checkout out Retrofit's Response object. It is a single pojo that contains both:

Both these fields are nullable, but one must be non-null and the other must be null. To know which field can be accessed, you have to check the .isSuccessful() flag.

Now imagine the verbosity if this best case scenario has to scale to 4 or more possible results. A whole new enum class would have to be added to work around it...it's not pretty.

Please add support for ADTs to Dart.

note: As an Android developer, I find that Flutter is an interesting proposition that is currently held back by the language.

adrianboyko commented 3 years ago

Sum types are not yet in the language funnel :(

Abion47 commented 3 years ago

@adrianboyko Check again under "Patterns and other features".

Nikitae57 commented 2 years ago

Another vote for this feature

aleksei-b-codexoptimus commented 2 years ago

How long can I wait? To write secure code, you have to suffer. Sealed classes have been implemented in all modern languages for a long time.

jjoelson commented 2 years ago

I'm not sure if commenting here will be helpful all, but I'm a big +1 to this feature request. When it comes to modeling a problem domain in a modern programming language, I'd say ADTs are very nearly as important as null safety. With null-safety implemented, I can't imagine any language feature that ought to be a higher priority than ADTs. It's similar to null-safety in the sense that you can't properly model your problem domain without it.

Flutter being such an important use of Dart implicitly puts Dart in direct competition with Swift and Kotlin. Both of those languages not only support ADTs, but have a strong developer culture of using them heavily. That means that while there is a lot about the developer experience that improves when one switches from native to Flutter, the lack of ADTs in Dart is a glaring regression that is very noticeable to iOS and Android devs.

He-Pin commented 2 years ago

I prefer we take a look at the Scala 3: https://docs.scala-lang.org/tour/case-classes.html https://docs.scala-lang.org/tour/pattern-matching.html https://docs.scala-lang.org/overviews/core/value-classes.html#inner-main https://docs.scala-lang.org/scala3/book/types-union.html https://docs.scala-lang.org/scala3/book/types-intersection.html https://docs.scala-lang.org/scala3/reference/enums/enums.html https://docs.scala-lang.org/scala3/book/types-opaque-types.html#inner-main

Abion47 commented 2 years ago

@hepin1989

JarvanMo commented 2 years ago

This is really awesome for Kotlin developers. You can say the current built-in types are enough for us but ENOUGH is far less than what we need. As a newer language, I believe we can do better in grammar sugar. I miss Kotlin very single time I write Flutter! I want data classes and removing the ;. And also enum class bring nothing but string and index! I can't say it can not work but I have to say I have to write more branches.

munificent commented 2 years ago

I want data classes and removing the ;.

These are tracked on separate issues.

And also enum class bring nothing but string and index!

The next stable release of Dart will allow you to define fields, methods, and other members on enum types. It's out in the beta channel now.

marcguilera commented 2 years ago

I think the overall experience writing dart is good but I do miss some things and by reading here it looks like I'm not alone. It would be great if we could have the equivalent of:

Packages like freezed are great but having to rely on code generation for this common cases feels sub optimal in my opinion.

The good news is that it looks like there are issues for most of these and are in various levels of discussions already. It's great we are getting fields in enums in the next release!

renatoathaydes commented 2 years ago

It's great we are getting fields in enums in the next release!

That was released in Dart 2.17 a few days ago. See the announcement: https://medium.com/dartlang/dart-2-17-b216bfc80c5d

munificent commented 1 year ago

Closing this because records and patterns are now enabled on the main branch of the Dart SDK! 🎉