DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Coding
  3. Languages
  4. Using Kotlin Scope Functions

Using Kotlin Scope Functions

Want to learn more about using Kotlin scope functions? Check out this post to learn more when you should consider refactoring your code and using scope functions

Uberto Barbini user avatar by
Uberto Barbini
·
Sep. 10, 18 · Tutorial
Like (10)
Save
Tweet
Share
9.82K Views

Join the DZone community and get the full member experience.

Join For Free

Do we really need yet another blog post on Kotlin scope functions?

As a matter of fact, I think we do! While there are many posts looking at this special function in Kotlin, I found none on how to pick up the correct function and when you should consider refactoring your code into using one of them.

I’ve tried to make it clear with the following diagram:

Use this means we are going to (mostly) call methods on a single object, the reference to the object is this.

Pass it means we need to pass the object to other methods/functions, the reference to the object is it.

Result means we will have a result value from the block and we need to return it.

Side-effects means we don’t expect a result but we want to call for some methods that return Unit (a.k.a. void) and maybe combine them in Fluent Interface style.

So, if you are wondering how to simplify code where an object (the target object) is used multiple times, you should ask yourself two questions:

Do I need to call methods on this object, or do I need to pass it as an argument to other methods/function?
Do I have a result at the end? Or, am I only changing the state?

 apply is useful if you need to call several methods on an object without caring for their return, like setters. Like the other three Extended Functions, if the target object is null, the block won’t be called, and inside the block, the object is always of a non-nullable type. For example:

fun updateItem(itemId: String, newName: String, newPrice: Double) = itemsMap.get(itemId)?.apply { 
    enabled = true
    desc = newName
    price = newPrice
}


with works almost exactly as apply ; the only difference is that if the object of a nullable type, then it will call the block anyway, passing the object as nullable. I use it only when there is a long block of code with some methods calling on a specific object, particularly if the var has a long name. For example:

// ... long method
val total = with(ridicurioslyLongNameOfFrameworkSingleton){ 
   setSomething(a)
   setSomethingElse(b)
// do other things...
   getTotal()
}
// ...


let is probably the most used, at least by me. It is particularly useful together with the question mark to obtain a result if a value is not null. You should consider removing any code that resemblesif (obj == null) {...} and use let or another scope function. For example:

fun fullName(firstName: String, middleName: String?, familyName: String) = middleName?.let{ 
   "$firstName ${it.first()}. $familyName"
} ?: "$firstName $familyName"


 run is useful if, at the end, calling a few methods on the object and one returns something else. For example:

fun cartTotal(cart: Cart, items: List<CartItem>) = cart.run{ 
   items.foreach{addItem(it)}
   calcTotal()
}


also is useful if you have a value that you need to return, but before returning, you also need to use it to do something else. For example:

fun createUser(userName: Stirng): Int =
    myAtomicInt.getAndIncrement().also { users.put(it, userName) }


As reference these are the signatures:

public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
public inline fun <T, R> T.run(block: T.() -> R): R = block()
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }


“I don’t see any advantage in using them, it’s just messing things around,” is a quite common objection that I heard when I showing code to people not familiar to Kotlin.

The lesser advantage of using a scope function is to save some lines of code. The greater advantage is to avoid temporary variables.

Temporary variables are usually a bad idea in functional programming, and they are a source of small bugs when you confuse them or you copy and paste some code around (which of course none of us ever do!).

In functional programming, style is also better (in the sense of transmitting a more clear intention) to use the single expression declaration form (that is fun f = …) for functions, and scope functions make it easier.

If you enjoyed this post, please be sure to give it a like! Thanks.

Kotlin (programming language) Object (computer science)

Published at DZone with permission of Uberto Barbini, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Best Practices for Writing Clean and Maintainable Code
  • Key Elements of Site Reliability Engineering (SRE)
  • 7 Ways for Better Collaboration Among Your Testers and Developers
  • Testing Repository Adapters With Hexagonal Architecture

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: