Search code examples
kotlinsemantics

Kotlin construction: function call with additional body - what such construction means or how it is called (if I want to look it up in the docs)?


I am seeing the Kotlin code:

    navController.navigate("sales_order/" + it.toString()) {
        popUpTo(navController.graph.findStartDestination().id) {
            saveState = true
        }
        launchSingleTop = true
        restoreState = true
    }

which I can describe as "function call" (navController.navigate) "with additional body" ({...}). How such construction is called (if I want to look it up in the docs) and what does it mean?

When I checked the type of navController.navigate(...) args, then there are 2 arguments. The first argument - string - is provided in () and I am trying to guess, that everything inside {...} is the content for the second argument which has type NavOptionsBuilder in this case. So, I can guess that NavOptionsBuilder has 3 arguments: 1 function call popUpTo that returns some object and 2 named arguments (launchSingleTop, restoreState) which are Boolean type.

Am I deciphering this construction right - just another way of passing arguments - or is there something deeper?


Solution

  • Am I deciphering this construction right

    Almost. You got the beginning right, but the end is not exactly correct.

    Let's start with what you got right, and throw in some vocabulary here for posterity. Indeed, you seem to be using the overload of navigate that takes 2 arguments: a string route and a builder function.

    Functions in kotlin can be passed in multiple ways, but the most common (and the one used here) is passing a lambda expression. Because the syntax for lambda expressions is based on braces ({ ... }), it makes it look like blocks of code, so the Kotlin language went one step further and allowed to pass lambda expressions outside of the parentheses of the function call when the lambda is the last argument. The reason for this is exactly to allow this kind of constructions which look like their own configuration language. This is what is usually referred to as DSLs (Domain Specific Languages).

    Now about what you got wrong:

    So, I can guess that NavOptionsBuilder has 3 arguments

    Not really. NavOptionsBuilder is the receiver of the function that is passed as the second argument of navigate. This means that, within the lambda that you pass, a NavOptionsBuilder instance is implicitly available as this.

    This, in turn, means that you can access methods and properties of NavOptionsBuilder within that lambda block. This is what popUpTo, launchSingleTop, and restoreState are: methods and properties of NavOptionsBuilder - not "arguments".

    You can find more general info about this here.