Smart Casts with Kotlin Contracts
Вставка
- Опубліковано 23 січ 2025
- Did you know that Kotlin can smart-cast a variable in response to calling your own functions? Well, today we’re going to use Kotlin's experimental Contracts feature to make that happen!
Contracts proposal:
github.com/Kot...
✨ New to Kotlin? Start here: typealias.com/...
... or pick up the new Leanpub Edition! book.typealias...
🚀 I just launched a new email newsletter!
Sign up here: newsletter.typ...
This is an exceptionally good video, as someone who has worked as a an engineer for 12 years there is a surprising lack of people who are good at communicating complex things effectively, in a way that is not meant to be understandable first, and concise / accurate next. There is a serious lack of such tutorials in the mobile dev space the focus on more advanced concepts.
Thank you so much, Syed! I'm really glad to hear that the concepts are conveyed effectively. I put a lot of effort into that goal, but I never really know if I achieved it until I get feedback from others - so, thank you again! 🙂
So happy to see a new video! I was yestarday talking about with a friend and saying how much potential you have as a Kotlin UA-camr! Please more!
Thanks so much, Wagner! I'm excited to finally publish a video with the new camera and studio setup that I've been working on for a while. 🙂 Definitely more videos coming!
@@typealias sounds exciting!
I completely agree. I think there is a gap on youtube for quality kotlin content Happy I found you :D
Thanks so much, Israel! I'll keep at it! 🙂
These videos continue to be amazing, well done!
Hey, thanks Jared! I'm excited about the new studio setup here! 🙂
Loved it , digging more hidden gems for us who is big big kotlin fan ...is just so so so helpful and amazing
thanks you sir, keep making more we are always here and waiting
Thanks so much, Raju! 🙂 I'll keep at it!
Great video Dave. Super high quality and the flow was really smooth. Great job!
Thanks so much, James! 🙂
Great video. Some comments/questions:
1. How do you look at the maintenance of this code? You've basically introduced a new function that depends on an experimental API. That's future maintenance.
2. With a sealed class, you get smart casting with the when clause. It's more explicit, but that's because it is reality: there may be more than two direct subtypes, which you cannot model with just a Boolean. E.g. consider that later you want to add a third type, e.g. an AuthenticatingUser (in the process of signing up or in). Now your contracts have to be refactored (deleted) because you can no longer model the type& authentication state with a Boolean. Is that a bad design choice? Is the example not good enough?
3. Kotlin really needs type unions. I've seen so many cases where that would be super useful. E.g. knowing that a user is not an AuthenticatedUser, but can be any of all other types (and if that's only 1, then it is that other type) would be helpful here. A more practical example would be to know that a server response is (not) of a certain type, e.g. if an API spec knows that a server will never respond 4xx errors, only 2xx or 5xx. But another server can respond 2xx or 4xx or 5xx. Then how do you model that once, without repeating yourself? Type unions would help a lot here. Another example: coroutines. While in a coroutine, any suspension point might throw a cancellation exception. This means you have to check for those (and not swallow them) everywhere you do some try-catch or runCatching, otherwise you'd break structured concurrency! Wouldn't it be nice to be able to catch all except cancellation? Type unions would solve that too.
Hi Erik - thanks for the comments!
1. Yes, it's definitely taking on risk to opt in to experimental features. For this feature in particular, it sounds very likely that the syntax of the contract DSL will change before it stabilizes, but the core concepts of the feature are unlikely to change. I'm expecting a small enough change that it wouldn't be much of a headache if using this feature in small quantities. You're the best judge of whether it's worth taking that risk on your own projects, of course, so do what you feel comfortable with!
2. You're right that if a third state emerges, then the shape of the code here becomes less valuable. In this video I modeled both the true and false sides of the contract, but you _could_ just model the "true" side - and in that case the third state would leave isAuthenticated() unaffected. If that were the case, though, I'd honestly favor just checking `if (user is AuthenticatedUser)` instead of `if (user.isAuthenticated())` because it's clearer to the developer. In any case, you're right that the emergence of a third state is another risk to this code.
3. I totally agree - I'd love to see union types in Kotlin! Been a while since we've had any update about them, but sounds like the Kotlin team might revisit them sometime after the K2 compiler is released (source: youtrack.jetbrains.com/issue/KT-13108/Denotable-union-and-intersection-types#focus=Comments-27-5474923.0-0). I can definitely understand how it'd be hard to add this to a language after it's already been established, though, so we'll see if it actually happens...
Well done, I've just subscribed and I am waiting for more!
Thank you so much! I'll keep at it!
Great! Please keep it up, we are always eagerly waiting for more from you.
Thanks so much, Fadi! I'll keep creating more videos! 😎
Great tip as always, Dave. Thanks!
You're most welcome, Ali! Glad you enjoyed it!
Great video, Dave. That was super clear and entertaining.
Hey Brady! Thanks so much! I'm glad you liked it! 😁
Love your videos. Kindly make weekly videos. Plsssss
Thanks, Ayodele! Weekly might be faster than I could manage, but I'll see what I can do! 😁
Your videos are very very high quality
Thanks so much! I'm glad you like them! 🙂
Excellent video! Keep that Kotlin content coming!
Thank you so much! Will do! 🙂
Finally you are back. You are building a gold mine, please don't stop
Thanks so much, Bawender! I'll keep at it! 😎
Thank you for sharing, I'm really enjoying your content!
Thank you so much, Stephen! I'm glad you're enjoying it! 🙂
Very good content man. very useful. Keep up the great work
Thanks so much! Will do!
Whoa, the explanation was very clear
Thanks, Eric! Very glad to hear that it was explained clearly - I always aim for that, of course, but I never know how I did until I hear from others about it. 🙂
Great!! nice concept in all your videos...!
Thank you very much, Matias! 🙂
This is super interesting. A strong parallel to Typescript's type guards. This could end up enabling monadic patterns to be expressed imperatively - imagine using this with the Maybe/Option monad.
Yes, that could be a really cool use for contracts! If you implement that, send me a link. I'd love to check it out.
Congratulations. Good job.
It's hard to come up with a short and rigorous explanation, but this one is.
Many thanks, Pedro! 🙂 Yes, it can be a challenge, but I'm glad to hear that this one achieved it!
amazing video!thank you Dave
Thank you so much, Andy! I'm glad you liked it! 🙂
Didnt know that,
Kotlin is awesome.
IntelliJ is awesome.
Jetbrains is awesome.
Your videos are awesome.
Hi Dave, thanks for your videos, very useful content
Thank you so much! 🙂
Very useful. Please consider using light theme for code blocks rather than dark theme as it's more accessible for those with astigmatism and more viewable at lower quality settings (for those with bad internet connections).
Thanks, Kiet - that's good to know!
Hi. How can I config the jetbrain IDE to get format-spacing as same as you (at 2:14). Many thanks.
Hello! Go to Settings/Preferences, and then Editor > Code Style > Kotlin, and then under "'when' statements", turn on the option for "Align 'when' branches in columns'. Once that's set, you should be able to go to Code > Reformat Code, and they should line up like they do in the video!
@@typealias thank you. I like your video.
Your website is awesome and your videos are polished and express what they need to very succinctly. I appreciate the respect for my time. But chalk me up with Mr. Grumpy Recalcitrant man on this one. Of course simplified examples can be strained but I just don't see a situation where a when statement results in more cognitive load than a contract.
Haha, thanks Neil - and yeah, it's totally fine to agree with Mr. Grumpy! Some language features are definitely more niche than others.
You had a new subscriber :)
Thanks, Zinou - I'm so glad to have you as a subscriber!
Hello, nice quality of video. Are you going to create more videos about Kotlin for beginners?
Hey, thanks so much! I'm happy to cover some beginner-level videos also. Are there any topics in particular that would be helpful for you?
@Dave Leeds Actually, I'm not sure what topics you enjoy 😄
However it would be nice to see content of language features (such as lambda expressions, async-await, concurrency), introduction, syntax, when features should be used etc. Jeffrey Way (the creator of Laracasts platform) did nice courses about PHP and Laravel framework, so you can be inspired by his content - just showing step by step, nice explanations of essential/fundamental topics.
Ideas for single video or full courses:
1. Creating simple microservices: list of available frameworks, how to use database (SQL/NoSQL), how to write application.
2. Kotlin application in Docker.
3. Gradle tutorial (what it is, how to use that, how to add packages, how to use packages both from Kotlin and Java).
4. Functional programming (what it is, how to write this way in Kotlin, maybe explaning features).
That's fantastic - thanks so much for the detailed list of ideas! I'll be sure to check out Jeffrey's videos.
Meanwhile, I'm working on some end-to-end video content that might fit what you're looking for, but it's still in "very early, closed access" mode. 🙂 I don't think UA-cam does private messaging any more, but if you're on Twitter, Mastadon, or LinkedIn (and if you're interested), feel free to send me a direct message, and I can point you at it.
Thanks again for the kind words and detailed feedback!
I am surprised by the quality of the video.
Thanks so much! I've been upgrading a few things. 🙂
Like from Belarus
amazing video! I am Mr.Grumpy Man, and I don't think this feature is necessary. I prefer more explicit and less abstraction.
Haha, yes - we're all Mr. Grumpy Recalcitrant Man at one point or another, depending on the feature we're talking about! 😁 When in doubt, it's probably best to err on the side of explicit types.
Mr. Grumpy is always right and Dave is always wrong. just kidding. using contracts to check if a variable is null or not, simplifies the code a lot and makes it less error prone
Haha, Mr. Grumpy usually has a good point! 😁
Although the video is informative, it can provoke validators instead of parsers which is an antipattern.